web-dev-qa-db-de.com

firebaseAuth.getCurrentUser () gibt null DisplayName zurück

Wenn ich mich bei meinem Google-Konto anmelde und den Namen mit dem getDisplayName () erhalte, wird mein Name korrekt angezeigt, im AuthStateListener jedoch nicht.

hier ein Teil meines Codes:

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

Aber in meinem AuthStateListener

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

        if (nuser != null) {

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

Weiß jemand, warum das passieren kann?

11

Dies ist eine schwierige Sache, da es in der Dokumentation nicht so klar ist ...

Überprüfen Sie die getProviderData (). 

wie hier definiert: https://firebase.google.com/docs/reference/Android/com/google/firebase/auth/FirebaseUser#public-method-summary

Sie können diese Liste durchlaufen und es werden alle Anbieter mit diesem Konto verknüpft. Dazu gehört ein Anbieter mit dem providerId = "google.com" mit einem Anzeigenamen = YOUR_GOOGLE_USERNAME

lass es mich wissen, wenn du es nicht schaffen kannst

7
Ymmanuel

Nur um Ymmanuel's Antwort (Danke!) Mit Beispielcode für alle anderen hinzuzufügen, die ein schnelles Kopieren und Einfügen wünschen:

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

Das obige wird versuchen, den ersten Anzeigenamen und die Foto-URL der Anbieter zu verwenden, wenn er nicht ursprünglich im Benutzerobjekt gefunden wurde.

Bonus: Verwenden von gleiten für Bilder: https://github.com/bumptech/glide .

7
Alan Haverty

Edmund Johnson hat recht. Dieses Problem wurde in Firebase Auth 9.8.0 eingeführt. Eine Problemumgehung umfasst das Herabstufen auf 9.6.1 oder das Erzwingen eines erneuten Anmeldens, wenn die Informationen aufgefüllt werden, nachdem sich der Benutzer abgemeldet und erneut angemeldet hat. Das Problem wird in Firebase-Problem beschrieben.

Es wurde von einem der Mitarbeiter der Firebase-Benutzeroberfläche - Alex Saveau - als Fehler in Firebase gemeldet.

4
Buli1212

Ich hatte das gleiche Problem. Ich habe das Problem gelöst, indem ich den Benutzer abgemeldet und zurückgezogen habe.

Rufen Sie FirebaseAuth.getInstance().signOut(); an, um sie abzumelden, und versuchen Sie es erneut. Wie ich festgestellt habe, tritt dieses Problem häufig auf, wenn Sie die E-Mail-/Passwort-Authentifizierung und das Social-Login (in meinem Fall Facebook) gleichzeitig verwenden.

2

Ich habe eine Lösung für dieses Problem in der Firebase-Dokumentation ! .__ gefunden. Die Lösung besteht darin, das Benutzerprofil mithilfe der folgenden Anweisungen zu aktualisieren: 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.");
                              }
                          }
                      });

Die Variable mUser ist bereits mit dem Inhalt aus den Feldern gefüllt . Ich habe diesen Code in FirebaseAuth.AuthStateListener () -> onAuthStateChanged ()

1
Mário Henrique

Dieses Problem wurde in der neuesten Version von Firebase ui behoben Compile 'com.firebaseui: firebase-ui: 1.2.0'

1
Raneez Ahmed

Ich bekam dieses Problem, als ich hatte:

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

Eine Problemumgehung, die es für mich behoben hat, war, das zu ersetzen durch:

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

Die Wiederholung durch user.getProviderData(), wie an anderer Stelle vorgeschlagen, wurde für die späteren Versionen nicht behoben.

0
Edmund Johnson

Lassen Sie mich zunächst sagen, dass es nicht nötig ist, die Gradle-Dateien herunterzuregeln oder den Benutzer mehrmals abzumelden und anzumelden, wie von anderen angegeben, um nur den Benutzernamen anzuzeigen. Ich habe das Problem auf eine andere Weise gelöst, wobei die neuesten Gradle-Dateien erhalten bleiben und der Benutzer nicht mehrmals abgemeldet werden muss. Das Problem mit getDisplayName() ist sehr groß, daher möchte ich den zukünftigen Benutzern von Firebase so beschreibend wie möglich sein, um ihnen die Kopfschmerzen zu ersparen.

Hier sind die Details der Lösung:

Lösung 1:

Für Benutzer, die sich bei mehreren Anbietern wie Facebook, Google usw. und/oder E-Mail/Passwort authentifizieren (anmelden), die sie bei der Anmeldung erstellt haben:

Als Erstes möchten Sie sicherstellen, dass Sie sich, wenn Sie einen Benutzer zum ersten Mal mit der App anmelden, ihren Namen natürlich in der Datenbank unter ihrer eindeutigen ID speichern. Was kann ungefähr so ​​aussehen:

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

}

Nachdem der Name des Benutzers in Ihrer Firebase-Datenbank gespeichert wurde und Sie sich in Ihrer App angemeldet haben, können Sie den Benutzernamen wie folgt erhalten:

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

    }

Das ist es. Jetzt nennst du einfach diese Methode showUserName() oder was auch immer deine Methode in deinem onCreate aufgerufen wird und hoffentlich hilft das.

Lösung 2:

Für Benutzer, die sich NUR bei einem Social-Media-Dienstanbieter wie Facebook, Twitter, Google oder einer anderen von Firebase möglichen Option bei Ihrer App anmelden: 

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

Das ist alles für Lösung 2, folgen Sie einfach den Richtlinien zu Firebase und Sie sollten gut sein. 

Hier ist ein Link, wenn Sie neugierig sind: Profilinformationen eines Benutzers abrufen

Ich hoffe wirklich, dass dies jedem hilft, der mit dem Thema getDisplayName() zu kämpfen hat. 

Fazit: 

Wenn Ihre App nur über Facebook, Twitter, Google oder andere Social-Media-Anmeldemöglichkeiten verfügt, die Firebase anbietet, reicht es aus, einfach getDisplayName()method für den aktuell angemeldeten Benutzer aufzurufen, um den Benutzernamen anzuzeigen.

Andernfalls, wenn Ihre App es dem Benutzer ermöglicht, sich mit einem von ihnen erstellten E-Mail/Passwort anzumelden, stellen Sie sicher, dass Sie ihren Namen/Benutzernamen bei der Anmeldung erhalten haben, damit Sie ihn später verwenden können, um ihn anzuzeigen.

0
Equivocal