web-dev-qa-db-fra.com

firebaseAuth.getCurrentUser () return null DisplayName

Lorsque je me connecte avec mon compte Google et que je reçois le nom avec getDisplayName (), mon nom s'affiche correctement, mais pas dans AuthStateListener.

voici une partie de mon code:

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

Mais dans mon AuthStateListener

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

        if (nuser != null) {

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

Quelqu'un sait pourquoi cela peut arriver?

11
Patricio Cornejo

C'est une question délicate car ce n'est pas si clair dans la documentation ...

Vérifiez le getProviderData () 

tel que défini ici: https://firebase.google.com/docs/reference/Android/com/google/firebase/auth/FirebaseUser#public-method-summary

Vous pouvez parcourir cette liste et tous les fournisseurs associés à ce compte seront inclus, y compris un fournisseur avec providerId = "google.com" avec un nom d'affichage = YOUR_GOOGLE_USERNAME.

laissez-moi savoir si vous ne pouvez pas le faire fonctionner

7
Ymmanuel

Juste pour ajouter à la réponse de Ymmanuel (Merci!) Avec un exemple de code pour ceux qui recherchent un copier-coller rapide:

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

Ce qui précède essaiera d'utiliser le premier nom d'affichage et l'URL de la photo du fournisseur s'il n'a pas été trouvé initialement dans l'objet Utilisateur.

Bonus: Utilisation de glide pour les images: https://github.com/bumptech/glide .

7
Alan Haverty

Edmund Johnson a raison. Ce problème a été introduit dans Firebase Auth 9.8.0. Une solution de contournement consiste à rétrograder à la version 9.6.1 ou à forcer une nouvelle connexion, les informations étant renseignées une fois que l'utilisateur s'est déconnecté et reconnecté. Le problème est décrit dans le problème de Firebase

L'un des contributeurs de l'interface utilisateur de Firebase, Alex Saveau, a signalé qu'il s'agissait d'un bogue dans Firebase.

4
Buli1212

J'ai eu le même problème, je l'ai résolu en déconnectant l'utilisateur et en le renvoyant.

Appelez FirebaseAuth.getInstance().signOut(); pour les déconnecter, puis réessayez ... Comme je l'ai découvert, ce problème est courant lorsque vous utilisez l'authentification par courrier électronique/mot de passe et la connexion sociale (Facebook dans mon cas) simultanément.

2
ojonugwa ochalifu

J'ai trouvé une solution à ce problème dans la documentation Firebase ! La solution consiste à mettre à jour le profil utilisateur à l'aide de: 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.");
                              }
                          }
                      });

La variable mUser est déjà renseignée avec le contenu des champs .J'ai utilisé ce morceau de code à l'intérieur de FirebaseAuth.AuthStateListener () -> onAuthStateChanged ()

1
Mário Henrique

Ce problème est résolu dans la dernière version de firebase ui Compile 'com.firebaseui: firebase-ui: 1.2.0'

1
Raneez Ahmed

Je devenais ce problème quand j'avais:

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

Une solution de contournement qui l'a corrigé pour moi était de remplacer cela par:

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

Itérer à travers user.getProviderData() comme suggéré ailleurs n'a pas résolu le problème pour les versions ultérieures.

0
Edmund Johnson

Tout d'abord, laissez-moi vous dire qu'il n'est pas nécessaire de rétrograder les fichiers Gradle ou de vous déconnecter et de vous connecter à l'utilisateur plusieurs fois, comme indiqué par d'autres personnes, uniquement pour afficher le nom d'utilisateur. J'ai résolu le problème différemment tout en conservant les fichiers Gradle les plus récents et en évitant de déconnecter l'utilisateur plusieurs fois. Le problème avec getDisplayName() est très important, je souhaite donc être le plus descriptif possible pour les futurs utilisateurs de Firebase afin de leur éviter le mal de tête.

Voici les détails de la solution:

Solution 1:

Pour les utilisateurs qui s'authentifient (se connectent) auprès de plusieurs fournisseurs tels que Facebook, Google, etc. et/ou les adresses e-mail/mots de passe créés lors de leur inscription:

La première chose que vous voulez vous assurer est que lorsque vous avez un utilisateur qui s’inscrit pour la première fois avec l’application, vous stockez bien sûr son nom dans la base de données sous son identifiant unique. Ce qui peut ressembler à quelque chose comme ça:

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

}

Une fois que le nom de l'utilisateur a été stocké dans votre base de données Firebase et que vous les avez connectés à votre application, vous pouvez obtenir leur nom d'utilisateur sous la forme suivante:

// 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

    }

C'est tout. Maintenant, vous appelez simplement cette méthode showUserName() ou quelle que soit votre méthode qui sera appelée dans votre onCreate et j'espère que cela vous aidera.

Solution 2:

Pour les utilisateurs qui se connectent à votre application en utilisant UNIQUEMENT un fournisseur de services de médias sociaux tel que Facebook, Twitter, Google ou toute autre option autorisée par 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();
    };
}

Voilà pour la solution 2, suivez simplement les instructions sur Firebase et vous devriez être bon. 

Si vous êtes curieux, voici un lien: Obtenir les informations du profil de l'utilisateur

J'espère sincèrement que cela aidera toute personne aux prises avec le problème getDisplayName()

Conclusion: 

Si votre application ne dispose que de Facebook, Twitter, Google ou de toute autre option de connexion aux médias sociaux proposée par Firebase, il suffit d'appeler getDisplayName()method sur l'utilisateur actuellement connecté qui devrait être suffisant pour afficher son nom d'utilisateur.

Sinon, si votre application permet à l'utilisateur de se connecter à l'aide d'un e-mail/mot de passe créé, assurez-vous que son nom/nom d'utilisateur lui a été attribué lors de l'inscription, de manière à pouvoir l'utiliser ultérieurement pour l'afficher.

0
Equivocal