【问题标题】:Why do we have to call getCurrentUser() several times Firebase?为什么我们必须多次调用 getCurrentUser() Firebase?
【发布时间】:2021-08-02 07:17:33
【问题描述】:

我正在创建一个日记应用程序。

我目前正在研究用户是否已经登录的功能——绕过“开始/登录活动”

在我正在观看的创建日记应用的视频中,讲师致电 mUser = firebaseAuth.getCurrentUser(); 多次。

他在onStart()onCreate()onAuthStateChanged() 中调用它。我可以理解为什么我们可能需要在onAuthStateChanged() 中再次调用它,但在这种情况下,我只是检查用户是否已经登录,所以它不应该与onCreate() 中收到的用户不同

我从onAuthStateChanged()onStart() 中删除了它,一切仍然正常。但是,我不确定它是否会在将来导致我出错。如果有人能证实这一点,我将不胜感激。 我们需要多次致电getCurrentUser() 有什么原因吗? 谢谢。

这是我的完整代码供参考:

public class MainActivity extends AppCompatActivity {
    Button getStarted;

    private FirebaseUser mUser;
    private FirebaseAuth firebaseAuth;
    private FirebaseAuth.AuthStateListener myListener;
    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private CollectionReference myCollectionRef = db.collection("Users");


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        firebaseAuth = FirebaseAuth.getInstance();
        mUser = firebaseAuth.getCurrentUser();




        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getStarted = findViewById(R.id.btnGetStarted);

        getStarted.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, LoginActivity.class));
                finish();
            }
        });

        myListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull @NotNull FirebaseAuth firebaseAuth) {
                if(mUser != null){
                    //logged in
                    
                    //I commented this out and everything is still working fine
                    //mUser = firebaseAuth.getCurrentUser();
                    String currentUserId = mUser.getUid();

                    myCollectionRef.whereEqualTo("userId", currentUserId).addSnapshotListener(new EventListener<QuerySnapshot>() {
                        @Override
                        public void onEvent(@Nullable @org.jetbrains.annotations.Nullable QuerySnapshot value, @Nullable @org.jetbrains.annotations.Nullable FirebaseFirestoreException error) {
                            if(error != null){
                                Log.d("my_error", error.toString());

                            }

                            if(!value.isEmpty()){
                                for(QueryDocumentSnapshot snapshot : value){
                                    JournalApi myJournalApi = new JournalApi();
                                    myJournalApi.setUsername(snapshot.getString("username"));
                                    myJournalApi.setId(snapshot.getString("userId"));

                                    startActivity(new Intent(MainActivity.this, JournalList.class));

                                    finish();
                                }
                            }
                        }
                    });
                }else{
                    //not logged in
                }
            }
        };


    }

    @Override
    protected void onStart() {
        super.onStart();

        //I commented this out and everything is still working fine
        //mUser = firebaseAuth.getCurrentUser();
        firebaseAuth.addAuthStateListener(myListener);
    }

    @Override
    protected void onPause() {
        super.onPause();

        if(firebaseAuth != null){
            firebaseAuth.removeAuthStateListener(myListener);
        }
    }
}

【问题讨论】:

    标签: java android firebase google-cloud-firestore firebase-authentication


    【解决方案1】:

    虽然登录是一个活动过程,但您的代码通过调用 signInWith 方法之一触发、维护身份验证状态并在应用重新启动时恢复它是后台进程,这些进程会在您使用 Firebase SDK 时自动发生。这很棒,因为这意味着您不必编写代码来保持令牌有效,或者检查用户个人资料是否已更改或他们的帐户是否已被禁用。

    但这确实意味着您不能在很长时间内可靠地将firebaseAuth.getCurrentUser() 的值缓存在变量中。如果您将值保存在变量中,然后 SDK 在后台更新身份验证状态,您的代码可能不再查看 firebaseAuth.getCurrentUser() 的正确值。

    这就是为什么您会看到比您预期更多的对firebaseAuth.getCurrentUser() 的调用,以及为什么您会在希望在身份验证状态更改时收到通知的地方看到firebaseAuth.addAuthStateListener,例如当用户登录时或由 SDK 输出。

    【讨论】:

    • 感谢您的回答!为什么有必要在 onCreate() 和 onStart() 中获取当前用户?我们不能只检查 onAuthStateChanged() 中的当前用户(这将包括登录、退出等所有过程)吗?谢谢。
    • 是的,一般来说,除了初始值之外,我更喜欢使用身份验证状态侦听器。由于您的代码必须有一些默认值,我倾向于在onCreate 中使用getCurrentUser(),因为它反映了该代码执行时的当前值。
    • 谢谢。但是 onStart() 是不必要的,对吗?
    • 这取决于一点。从理论上讲,onAuthStateChanged 可能会稍后触发,因为 SDK 可能(在后台)确定初始状态。 SDK 会阻止它在初始检查完成之前触发,因此其中可能存在“未知状态期”。但是将当前用户初始化为null 将与实际检查它相同。
    • 谢谢。不过我还是有点困惑。如果我说 mUser = getCurrentUser(); 为什么 currentUser 会为空?在 onStart() 中——即使它在 onAuthStateChanged 之前被解雇?谢谢。
    【解决方案2】:

    您必须在每次要检查用户当前会话时调用此方法,因为用户的会话可以从另一个服务或方法更改,如果您不调用此方法而只调用一次,您将没有最新用户的个人资料信息、身份验证会话等。

    【讨论】:

      猜你喜欢
      • 2014-02-16
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多