firebaseAuth.getCurrentUser()返回null DisplayName

时间:2016-06-06 15:51:47

标签: android firebase firebase-authentication

当我使用我的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 
        }
    }

有人知道为什么会这样吗?

9 个答案:

答案 0 :(得分:7)

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

检查getProviderData()

如此处所定义: https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseUser#public-method-summary

您可以迭代该列表,它将拥有与该帐户相关联的所有提供商,包括提供商,其中包含providerId =&#34; google.com&#34;显示名称= YOUR_GOOGLE_USERNAME

如果你不能让它发挥作用,请告诉我

答案 1 :(得分:7)

只需添加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对象中找到,则上面将尝试使用提供者的第一个显示名称和照片网址。

加分:使用图片滑行:https://github.com/bumptech/glide

答案 2 :(得分:4)

爱德蒙约翰逊是对的。 Firebase Auth 9.8.0中引入了此问题。解决方法包括降级到9.6.1或强制重新登录&#39;在用户注销并重新登录后填充信息。问题在Firebase issue

中描述

Firebase UI贡献者之一Alex Fireau已将此消息报告给Firebase。

答案 3 :(得分:2)

我遇到了同样的问题,我通过退出用户并将其重新签名来解决问题。

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

答案 4 :(得分:1)

我在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() - &gt;中使用了这段代码。 onAuthStateChanged()

答案 5 :(得分:1)

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

答案 6 :(得分:0)

我遇到这个问题时遇到了这个问题:

<section id="burger-box">
  <div id="cpBtn">
    <div></div>
    <div></div>
    <div></div>
  </div>  
</section>
<style>
#burger-box     {
  float:right;
  width:80px;  
  height:70px;
  top:0;
  right:0;
  background:rgba(34,34,34,1);
  position:fixed;
  z-index:101}
#burger-box > #cpBtn {
  width:40%;
  height:25px;
  cursor:pointer;
  padding:25px 30% 20px 30%
}
#burger-box > #cpBtn > div {
  left:0;
  width:100%;
  height:2px;
  background:#fff;
  background:linear-gradient(to left, #fff 50%, #E18767 50%);
  background-size:200% 100%;
  background-position:right bottom;
  margin:6px 0;
  transition:background 1.75s ease
}
#burger-box > #cpBtn > div:hover {
  background:#E18767
 }
#burger-box > #cpBtn:hover > div {
  background:#E18767;
  background-position:left bottom
}
</style>

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

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

按照其他地方的建议对compile 'com.google.firebase:firebase-auth:9.6.0' compile 'com.firebaseui:firebase-ui-auth:0.6.0' 进行迭代并没有为以后的版本修复它。

答案 7 :(得分:0)

首先让我说,没有必要降级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()方法就足以显示其用户名。

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

答案 8 :(得分:0)

根据艾伦(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;
}