我是Firebase的新手,而且我在异步调用所有任务时遇到了很多问题。
例如,我正在尝试使用fetchProvidersForEmail来了解我是否应该指示用户注册或登录。但是,当任务完成时,为时已晚。
我不确定它是否清楚,但这是我当前的代码(有效),下面是我想要创建的方法。我该怎么做呢?
public static void printProviders(String email) {
FirebaseAuth auth = FirebaseAuth.getInstance();
auth.fetchProvidersForEmail(email).addOnCompleteListener(new OnCompleteListener<ProviderQueryResult>() {
@Override
public void onComplete(@NonNull Task<ProviderQueryResult> task) {
Log.d(TAG, "We have " + task.getResult().getProviders().size() + " results.");
for (int i = 0; i < task.getResult().getProviders().size(); i++) {
Log.d(TAG, "Provider " + (i+1) + ": " + task.getResult().getProviders().get(i));
}
}
}
);
}
以下是我想要创建的方法的伪代码(当然,这不起作用)......
public static boolean emailIsRegistered(String email) {
FirebaseAuth auth = FirebaseAuth.getInstance();
auth.fetchProvidersForEmail(email).addOnCompleteListener(new OnCompleteListener<ProviderQueryResult>() {
@Override
public void onComplete(@NonNull Task<ProviderQueryResult> task) {
if (task.getResult().getProviders().size() > 0) {
return true;
}
return false;
}
});
}
但是,这不起作用,因为返回语句对于onComplete()是无效的,并且因为该任务是异步执行的......
我是新手。我试图通过StackOverflow搜索,但无法找到任何帮助我的东西。希望有人可以提供帮助。
谢谢!
答案 0 :(得分:4)
当您致电fetchProvidersForEmail
时,您的应用的APK中没有该信息。 Firebase客户端必须调用服务器才能获取此信息。
鉴于互联网的性质,这意味着在结果从这些服务器返回之前需要一段不确定的时间。
客户可以选择在此期间做什么:
等待数据意味着您的代码保持简单。但这也意味着在查找数据时您的应用程序被阻止。所以:没有微调器动画会运行,用户不能做任何其他事情(这可能适用于您的应用程序,但不适用于其他人),等等。这被视为糟糕的用户体验。实际上很糟糕,Android will show an Application Not Responding dialog if your app is in this state for 5 seconds。
相反,Firebase SDK会选择其他选项:他们会让代码继续运行,同时他们会从服务器中检索数据。然后,当检索到数据时,它们会回调您提供的代码块。大多数现代Web API都是以这种方式构建的,因此您越早掌握它,就越能有效地使用这些API。
我发现掌握异步编程的最简单方法是重构问题。现在,您正在尝试&#34;首先确定电子邮件是否已被使用,然后向上或在&#34;中签署用户。
if (emailIsRegistered(email)) {
signInUser(email);
}
else {
signUpUser(email);
}
这种方法导致{em>返回布尔值的emailIsRegistered
方法,这是异步方法无法实现的。
现在让我们将问题重新设置为&#34;确定电子邮件是否已被使用。当我们知道这一点时,请在用户上签名或在&#34;中签名。
这导致了不同的代码:
public static boolean emailIsRegistered(String email) {
FirebaseAuth auth = FirebaseAuth.getInstance();
auth.fetchProvidersForEmail(email).addOnCompleteListener(new OnCompleteListener<ProviderQueryResult>() {
@Override
public void onComplete(@NonNull Task<ProviderQueryResult> task) {
if (task.getResult().getProviders().size() > 0) {
signUserIn(email);
}
signUserUp(email);
}
});
我们已将要求用户注册或的调用移至 现在,这当然将后续操作硬编码到 学习处理异步调用既困难又重要。我不确定这是否是我对这些概念的最佳解释。所以我将包括一些先前的解释(来自我和其他人):emailIsRegistered
方法,然后在结果可用时调用。< / p>
emailIsRegistered
方法中,这使得重用更加困难。这就是为什么你经常看到回调被传递到这些函数中的原因。一个很好的例子就是您已经使用的OnCompleteListener
。 Firebase客户端从服务器获取结果后,会调用您传入的onComplete
方法。