Firebase - Android - fetchProvidersForEmail - 为什么所有调用都是异步的? [英] Firebase - Android - fetchProvidersForEmail - Why are all the calls asynchronous?

查看:18
本文介绍了Firebase - Android - fetchProvidersForEmail - 为什么所有调用都是异步的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Firebase 的新手,我遇到了很多问题,因为所有任务都是异步调用的.

I'm new to Firebase and I'm having a lot of problems with the fact that all the tasks are called asynchronously.

例如,我正在尝试使用 fetchProvidersForEmail 来了解我是否应该引导用户注册或登录.但是,当任务完成时,为时已晚.

For example, I am trying to use fetchProvidersForEmail to know if I should direct the user to sign up or log in. However, by the time the task finishes, it's too late.

我不确定它是否清楚,但这是我当前的代码(有效),下面是我想要创建的方法.我怎样才能做到这一点?

I am not sure if it's clear but here is my current code (which works) and below is the method I would want to create. How can I get that done?

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));
                }
            }
        }
    );
}

这是我想要创建的方法的伪代码(当然,这不起作用)...

Here is the pseudo-code of the method I would want to create (of course, this doesn't work)...

    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() 是无效的,并且因为任务是异步执行的...

However, this does not work because the return statement is void for onComplete() and because the task is executed asynchronously...

我是新手.我试图通过 StackOverflow 进行搜索,但找不到任何对我有帮助的内容.希望有人能帮忙.

I am new to this. I tried to search through StackOverflow but couldn't find anything that helped me. Hopefully someone can help.

谢谢!

推荐答案

当您调用 fetchProvidersForEmail 时,该信息在您应用的 APK 中不可用.Firebase 客户端必须调用服务器以获取此信息.

When you call fetchProvidersForEmail that information is not available in the APK of your app. The Firebase client has to call out to the servers to get this information.

鉴于互联网的性质,这意味着结果从这些服务器返回之前需要不确定的时间.

Given the nature of the internet, this means that it will take an undetermined amount of time before the result comes back from those servers.

客户在此期间有几个选择:

The client has a few options on what to do in the meantime:

  1. 等待数据可用
  2. 继续执行并在数据可用时给您回电

等待数据意味着您的代码保持简单.但这也意味着在查找数据时您的应用程序被阻止.所以:没有旋转动画会运行,用户不能做任何其他事情(这可能对你的应用程序很好,但对其他人来说不是)等等.这被认为是一种糟糕的用户体验.事实上很糟糕,Android 将显示应用程序无响应对话框,如果您的应用程序是在此状态下保持 5 秒.

Waiting for the data would mean that your code stays simple. But it also means that your app is blocked while the data is being looked up. So: no spinner animation would run, the user can't do anything else (which may be fine for your app, but not for others), etc. This is considered a bad user experience. So bad in fact, that Android will show an Application Not Responding dialog if your app is in this state for 5 seconds.

因此,Firebase SDK 选择了另一个选项:它们让您的代码继续,同时从服务器检索数据.然后,当检索到数据时,它们会回调到您提供的代码块中.大多数现代 Web API 都是以这种方式构建的,因此您越早掌握它,您就能越早有效地使用这些 API.

So instead, the Firebase SDKs choose the other option: they let your code continue, while they're retrieveing the data from the servers. Then when the data is retrieved, they call back into a code block you provided. Most modern web APIs are built this way, so the sooner you come to grips with it, the sooner you can efficiently use those APIs.

我发现掌握异步编程的最简单方法是重构您的问题.现在,您正在尝试首先确定电子邮件是否已被使用,然后让用户注册或登录".

The easiest way I found to grasps asynchronous programming is by reframing your problems. Right now you're trying to "first determine if the email is already used, then sign the user up or in".

if (emailIsRegistered(email)) {
    signInUser(email);
}
else {
    signUpUser(email);
}

这种方法导致 emailIsRegistered 方法返回一个布尔值,这是异步方法不可能实现的.

This approach leads to a emailIsRegistered method that returns a boolean, something that is impossible with asynchronous methods.

现在让我们将问题重新定义为确定电子邮件是否已被使用.当我们知道这一点后,请用户注册或登录".

Now let's reframe the problem to "determine if the email is already used. When we know this, sign the user up or in".

这导致了一段不同的代码:

This leads to a different piece of code:

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 方法中,然后在结果可用时调用.

We've moved the calls to sign the user up or in into the emailIsRegistered method and invoke then when the result becomes available.

现在这当然将后续操作硬编码到 emailIsRegistered 方法中,这使得重用变得更加困难.这就是为什么您经常看到回调被传递到这些函数中的原因.一个很好的例子是您已经在使用的 OnCompleteListener.Firebase 客户端从服务器获取结果后,它会调用您传入的 onComplete 方法.

Now this of course hard-coded the follow up action into the emailIsRegistered method, which makes it harder to re-use. That's why you quite often see a callback being passed into these functions. A great example of that is the OnCompleteListener that you're already using. Once the Firebase client gets the result from the servers, it calls the onComplete method that you passed in.

学习处理异步调用既困难又重要.我不确定这是否是我对这些概念最好的解释.所以我将包括一些之前的解释(来自我和其他人):

Learning to deal with asynchronous calls is both hard and important. I'm not sure if this is my best explanation of the concepts ever. So I'll include some previous explanations (from both me and others):

这篇关于Firebase - Android - fetchProvidersForEmail - 为什么所有调用都是异步的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆