【问题标题】:firebaseAuth.getCurrentUser() return null DisplayNamefirebaseAuth.getCurrentUser() 返回 null DisplayName
【发布时间】:2016-10-06 07:35:18
【问题描述】:

当我使用我的 google 帐户登录并使用 getDisplayName() 获取名称时,我的名称显示正确,但在 AuthStateListener 中却没有。

这是我的代码的一部分:

private void handleSignInResult(GoogleSignInResult result) {

    Alert.dismissProgress();

    if (result.isSuccess()) {
        GoogleSignInAccount acct = result.getSignInAccount();

        if(acct != null) {
            Log.i("NAME", acct.getDisplayName()); <-- RETURN MY NAME CORRECTLY
            credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
            fuser.linkWithCredential(credential).addOnCompleteListener(authResult);                    
        } else {
            //ERROR
        }

    } else {
        //ERROR
    }
}

但在我的 AuthStateListener 中

@Override
    public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
        FirebaseUser nuser = firebaseAuth.getCurrentUser();

        if (nuser != null) {

            Log.i("NAME", nuser.getDisplayName()); <--- RETURN NULL 
        }
    }

有人知道为什么会发生这种情况吗?

【问题讨论】:

    标签: android firebase firebase-authentication


    【解决方案1】:

    这是一个棘手的问题,因为它在文档中不是很清楚......

    检查 getProviderData()

    在这里定义: https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseUser#public-method-summary

    您可以迭代该列表,它将拥有与该帐户关联的所有提供商,包括一个 providerId = "google.com" 的提供商,其显示名称 = YOUR_GOOGLE_USERNAME

    如果你不能让它工作,请告诉我

    【讨论】:

    • 谢谢! getProviderData() 返回我 2 个用户信息,所以我可以选择 google.com 信息,但仍然很奇怪,如果我链接新用户,它应该只显示新用户而不是两者……但仍然有效;)跨度>
    • 是的,我注意到了一些 firebase 奇怪的东西.....例如在 iOS 中,匿名密钥在自定义身份验证和匿名身份验证时返回匿名 = true,而在 android custom = false 和匿名 = 真
    【解决方案2】:

    只是在 Ymmanuel 的回答中添加一些示例代码(谢谢!),以供其他任何寻求快速复制和粘贴的人使用:

    FirebaseUser user = firebaseAuth.getCurrentUser();
    if (user != null) {
        // User is signed in              
        String displayName = user.getDisplayName();
        Uri profileUri = user.getPhotoUrl();
    
        // If the above were null, iterate the provider data
        // and set with the first non null data
        for (UserInfo userInfo : user.getProviderData()) {
            if (displayName == null && userInfo.getDisplayName() != null) {
                displayName = userInfo.getDisplayName();
            }
            if (profileUri == null && userInfo.getPhotoUrl() != null) {
                profileUri = userInfo.getPhotoUrl();
            }
        }
    
        accountNameTextView.setText(displayName);
        emailTextView.setText(user.getEmail());
        if (profileUri != null) {
            Glide.with(this)
                    .load(profileUri)
                    .fitCenter()
                    .into(userProfilePicture);
        }
    }
    

    如果最初在 User 对象中没有找到,上面将尝试使用来自提供者的第一个显示名称和照片 url。

    奖励:使用滑行图像:https://github.com/bumptech/glide .

    【讨论】:

      【解决方案3】:

      埃德蒙·约翰逊是对的。这个问题是在 Firebase Auth 9.8.0 中引入的。解决方法包括降级到 9.6.1 或在用户注销并重新登录后填充信息时强制“重新登录”。Firebase issue

      中描述了该问题

      Firebase UI 贡献者之一 - Alex Saveau 已将它作为一个错误报告给 Firebase。

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,我通过注销用户并重新登录来解决它。

        致电FirebaseAuth.getInstance().signOut(); 将其注销,然后重试。 正如我所发现的,这个问题在同时使用电子邮件/密码身份验证和社交登录(在我的例子中是 Facebook)时很常见。

        【讨论】:

          【解决方案5】:

          我在Firebase documentation! 中找到了解决此问题的方法! 解决方案是使用以下命令更新用户配置文件:UserProfileChangeRequest

          UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
                                .setDisplayName(mUser.getName())
                                .setPhotoUri(Uri.parse("https://example.com/mario-h-user/profile.jpg"))
                                .build();
          
                      firebaseUser.updateProfile(profileUpdates)
                                .addOnCompleteListener(new OnCompleteListener<Void>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Void> task) {
                                        if (task.isSuccessful()) {
                                            Log.d(TAG, "User profile updated.");
                                        }
                                    }
                                });
          

          变量 mUser 已经填充了字段中的内容。 我在 FirebaseAuth.AuthStateListener() -> onAuthStateChanged()

          中使用了这段代码

          【讨论】:

            【解决方案6】:

            此问题已在最新版本的 firebase ui 中得到解决 编译'com.firebaseui:firebase-ui:1.2.0'

            【讨论】:

              【解决方案7】:

              首先让我说没有必要降级Gradle文件或注销并像其他人所说的那样多次登录用户只是为了显示用户名。我以不同的方式解决了这个问题,同时仍然保留了最新的 Gradle 文件,而不必多次注销用户。 getDisplayName() 的问题是一个非常大的问题,因此我希望尽可能为 Firebase 的未来用户提供描述性,以免他们头疼。

              以下是解决方案的详细信息:

              解决方案 1:

              对于通过多个提供商(例如 Facebook、Google 等)和/或他们在注册时创建的电子邮件/密码进行身份验证(登录)的用户:

              您要确保的第一件事是,当您有用户第一次注册应用程序时,您当然会将他们的姓名存储到数据库中,并使用他们的唯一 ID。可能看起来像这样:

              // Method signature. Write current user's data to database
              private void writeNewUser(String userId, String name, String email) {
              
              DatabaseReference current_user_database = mDatabaseRef.child(userId);
              
              current_user_database.child("username").setValue(name);
              
              // Email here is not mandatory for the solution. Just here for clarity of the
              // method signature
              current_user_database.child("email").setValue(email);
              
              }
              

              用户名存储在您的 Firebase 数据库中并且您让他们登录您的应用后,您可以获取他们的用户名,如下所示:

              // Method that displays the user's username
                  private void showUserName() {
              
                      // Get instance of the current user signed-in
                      mFirebaseUser = mAuth.getCurrentUser();
              
                      // Check if user using sign-in provider account is currently signed in
                      if (mFirebaseUser != null) {
              
              
                          // Get the profile information retrieved from the sign-in provider(s) linked to a user
                          for (UserInfo profile : mFirebaseUser.getProviderData()) {
              
                                  // Name of the provider service the user signed in with (Facebook, Google, Twitter, Firebase, etc.)
                                  String name = profile.getDisplayName();
              
              
              // If displayName() is null this means that the user signed in using the email and password they created. This is the null issue we shouldn't get that we are gonna be solving below. 
                              if(name == null){
              
                                  mDatabaseRef.addValueEventListener(new ValueEventListener() {
                                      @Override
                                      public void onDataChange(DataSnapshot dataSnapshot) {
              
              // Get the name the user signed-up with using dataSnapshot
                                          String nameOfCurrentUser = (String) dataSnapshot.child("name").getValue();
              
              // Set username we retrieved using dataSnapshot to the view
                                          mTestUsernameTextView.setTitle(nameOfCurrentUser);
              
                                      }
              
                                      @Override
                                      public void onCancelled(DatabaseError databaseError) {
              
                                      }
                                  });
                              }
              
              // If the name is not null that means the user signed in with a social Auth provider such as Facebook, Twitter, Google etc.
                              if(name != null) {
              
                                  // Set the TextView (or whatever view you use) to the user's name.
                                  mTestUsernameTextView.setText(name);
              
                              }
              
                          } // End for
              
                      } // End if
              
                  }
              

              就是这样。现在您只需调用该方法 showUserName() 或在 onCreate 中调用您的任何方法,希望这会有所帮助。

              解决方案 2:

              对于仅使用社交媒体服务提供商(例如 Facebook、Twitter、Google 或 Firebase 允许的任何其他选项)登录您的应用的用户:

              FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
              if (user != null) {
                  for (UserInfo profile : user.getProviderData()) {
                      // Id of the provider (ex: google.com)
                      String providerId = profile.getProviderId();
              
                      // UID specific to the provider
                      String uid = profile.getUid();
              
                      // Name, email address, and profile photo Url
                      String name = profile.getDisplayName();
                      String email = profile.getEmail();
                      Uri photoUrl = profile.getPhotoUrl();
                  };
              }
              

              解决方案 2 就是这样,只需按照 Firebase 上的指南进行操作,就可以了。

              如果你好奇,这里有一个链接: Get a user's profile information

              我真的希望这可以帮助任何在getDisplayName() 问题上苦苦挣扎的人。

              结论:

              如果您的应用只有 Facebook、Twitter、Google 或 Firebase 提供的任何其他社交媒体登录选项,那么只需对当前登录的用户调用 getDisplayName()method 就足以显示他们的用户名。

              否则,如果您的应用允许用户使用他们创建的电子邮件/密码登录,请确保您在注册时获得了他们的姓名/用户名,以便您以后可以使用它来显示它。

              【讨论】:

                【解决方案8】:

                当我遇到这个问题时:

                implementation 'com.google.firebase:firebase-auth:10.0.0'
                implementation 'com.firebaseui:firebase-ui-auth:1.0.1'
                

                为我修复它的解决方法是将其替换为:

                implementation 'com.google.firebase:firebase-auth:9.6.0'
                implementation 'com.firebaseui:firebase-ui-auth:0.6.0'
                

                按照其他地方的建议遍历user.getProviderData() 并没有为以后的版本修复它。

                【讨论】:

                  【解决方案9】:

                  根据 Alan 和 Ymmanuel 的回答,这是我正在使用的 2 个辅助方法:

                  public static String getDisplayName(FirebaseUser user) {
                      String displayName = user.getDisplayName();
                      if (!TextUtils.isEmpty(displayName)) {
                          return displayName;
                      }
                  
                      for (UserInfo userInfo : user.getProviderData()) {
                          if (!TextUtils.isEmpty(userInfo.getDisplayName())) {
                              return userInfo.getDisplayName();
                          }
                      }
                  
                      return null;
                  }
                  
                  public static Uri getPhotoUrl(FirebaseUser user) {
                      Uri photoUrl = user.getPhotoUrl();
                      if (photoUrl != null) {
                          return photoUrl;
                      }
                  
                      for (UserInfo userInfo : user.getProviderData()) {
                          if (userInfo.getPhotoUrl() != null) {
                              return userInfo.getPhotoUrl();
                          }
                      }
                  
                      return null;
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2022-01-16
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-01-18
                    • 2021-08-23
                    • 2020-11-21
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多