2016-06-06 22 views
9

Quando eseguo l'accesso con il mio account google e ottengo il nome con getDisplayName(), il mio nome viene visualizzato correttamente, ma in AuthStateListener no.firebaseAuth.getCurrentUser() restituisce null DisplayName

qui parte del mio codice:

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

Ma nel mio AuthStateListener

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

     if (nuser != null) { 

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

Qualcuno sa perché questo può accadere?

risposta

6

Questo è un ingannevole dal momento che non è così chiaro nella documentazione ...

Controllare il getProviderData()

come definito qui: https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseUser#public-method-summary

È possibile scorrere l'elenco e avrà tutti i provider associati a quell'account, incluso un provider con providerId = "google.com" con un nome visualizzato = YOUR_GOOGLE_USERNAME

fammi sapere se non puoi farlo funzionare

+0

Grazie! getProviderData() mi restituisce 2 informazioni sugli utenti, quindi posso selezionare le informazioni su google.com, ma ancora strano che se collego il nuovo utente dovrebbe mostrarmi solo il nuovo utente e non entrambi ... ma funziona ancora;) –

+0

Sì ho notato un paio di cose strane firebase ..... come ad esempio in iOS la chiave anonima restituisce anonymous = true con autenticazione personalizzata e con autenticazione anonima mentre in android custom = false e anonymous = true – Ymmanuel

6

Giusto per aggiungere alla risposta di Ymmanuel (Grazie!) con un certo codice di esempio per chiunque altro alla ricerca di una copia rapida e incolla:

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

È possibile che cercherà di utilizzare il primo nome visualizzato e l'url di foto dai provider se inizialmente non è stato trovato nell'oggetto Utente.

Bonus: Utilizzo della planata per immagini: https://github.com/bumptech/glide.

0

mi è stato sempre questo problema quando ho avuto:

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

Una soluzione che ha risolto il tutto per me era quello di sostituire quello con:

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

scorrendo user.getProviderData() come suggerito altrove non lo fece correggilo per le versioni successive.

3

Edmund Johnson ha ragione. Questo problema è stato introdotto in Firebase Auth 9.8.0. Una soluzione alternativa include il downgrade a 9.6.1 o il "re-login" quando l'informazione viene popolata dopo che l'utente si disconnette e si registra nuovamente. Il problema è descritto nel Firebase issue

È stato segnalato come errore di Firebase da uno dei contributori dell'interfaccia utente di Firebase - Alex Saveau.

1

Ho avuto lo stesso problema, ho risolto con la firma l'utente e le dimissioni di nuovo in.

chiamata FirebaseAuth.getInstance().signOut(); di firmarli, poi riprovare. Come ho scoperto, questo problema è comune con l'utilizzo di autenticazione email/password e accesso social (Facebook nel mio caso) allo stesso tempo.

0

Prima lasciatemi dire che non è necessario eseguire il downgrade dei file Gradle o il logout e accedere più volte all'utente come indicato da altri solo per visualizzare il nome utente. Ho risolto il problema in un modo diverso pur mantenendo gli ultimi file Gradle e senza dover disconnettere l'utente e in più volte. Il problema con getDisplayName() è molto grande quindi voglio essere il più descrittivo possibile per i futuri utenti di Firebase per risparmiare loro il mal di testa.

Ecco i dettagli della soluzione:

Soluzione 1:

Per gli utenti che eseguono l'autenticazione (sign-in) con più fornitori come Facebook, Google ecc e/o e-mail/Password creata al momento della registrazione:

La prima cosa che si vuole assicurare è che quando si registra un utente con l'app per la prima volta si memorizza il proprio nome nel database sotto il loro unico id. Che può essere simile a questa:

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

} 

Dopo il nome dell'utente è stato memorizzato nel database Firebase e si dispone di loro firmare nella vostra applicazione è possibile ottenere il loro nome utente qualcosa di simile:

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

    } 

Ecco esso. Ora chiami quel metodo showUserName() o qualunque sia il tuo metodo verrà chiamato all'interno del tuo onCreate e speriamo che questo aiuti.

Soluzione 2:

Per gli utenti che si iscrivono nella vostra applicazione utilizzando solo un fornitore di servizi di social media come Facebook, Twitter, Google o qualsiasi altra opzione Firebase permette:

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

È tutto per la soluzione 2, basta seguire le linee guida su Firebase e dovresti essere bravo.

Ecco un link ad esso se siete curiosi: Get a user's profile information

Spero davvero che questo aiuta tutti coloro che lottano con il problema getDisplayName().

Conclusione:

Se la vostra applicazione ha solo Facebook, Twitter, Google o qualsiasi altra cosa le opzioni di accesso altro social media Firebase fornisce poi basta semplicemente chiamando getDisplayName() metodo sul attualmente firmato a utente dovrebbe essere sufficiente a dimostrare il loro nome utente.

In caso contrario, se l'app consente all'utente di accedere utilizzando una e-mail/password creata, assicurarsi di ottenere il proprio nome/nome utente al momento dell'iscrizione in modo da poterlo utilizzare in un secondo momento per visualizzarlo.

0

Ho trovato una soluzione per questo problema, nel Firebase documentation! La soluzione è aggiornare il profilo utente utilizzando: 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 variabile muser è già riempito con il contenuto dei campi. Ho usato questo pezzo di codice all'interno del FirebaseAuth.AuthStateListener() -> onAuthStateChanged()

0

Questo problema è stato risolto nell'ultima verison di Firebase ui compilazione 'com.firebaseui: Firebase-ui: 1.2.0 '