Reputation: 161
I am developing an Android App using Firebase, In my app I am using Firebase Anonymous Login and Google sign In.
When the application starts if the user is not Logged In, then I am using Anonymous Authentication to log the user in.
Afterwards when user chooses to Sign In using Google, then I am converting Anonymous Account to a permanent account.
My issue over here is, When user's account is converted from Anonymous Account to permanent account (using Google Sign In in this case), I am not getting User's Display Name and Photo Url.
For converting from Anonymous Account to permanent account I am using below code.
AuthCredential credential = GoogleAuthProvider.getCredential(googleIdToken, null);
mAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(TAG, "linkWithCredential:onComplete:" + task.isSuccessful());
if (!task.isSuccessful()) {
Toast.makeText(AnonymousAuthActivity.this, "Authentication failed.",Toast.LENGTH_SHORT).show();
//If Google Account already linked up with other UID
Tasks.await(mAuth.signInWithCredential(credential)).getUser();
}
}
});
After the Sign In process completes, the AuthStateListener onAuthStateChanged is called, Then in onAuthStateChanged I am extracting User's Display Name, User's Photo Url and User's Email. Below is the onAuthStateChanged code.
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null && !(user.isAnonymous())) {
Log.d("userDetails", "UID: " + user.getUid());
Log.d("userDetails", "Name: " + user.getDisplayName());
Log.d("userDetails", "PhotoUrl: " + user.getPhotoUrl().toString());
Log.d("userDetails", "Email: " + user.getEmail());
}
In the log I am getting null for user.getDisplayName() and user.getPhotoUrl()
I don't understand what I am doing wrong. Please help.
Thanks & Regards,
Upvotes: 11
Views: 3717
Reputation: 204
When linking accounts (or even on every sign in), call this function
Future<void> updateMissingUserPropertise(User user) async {
if (user.photoURL == null) await user.updatePhotoURL(user.providerData[0].photoURL);
if (user.displayName == null) await user.updateDisplayName(user.providerData[0].displayName);
}
In order to support multiple providers, each of which might hold a different name, photo, or phone number, Firebase auth does not modify the user properties when linking accounts.
Even if the user signs out later and signs in with Google, or any other federated account, it does not change the user properties.
The function above 'fixes' the missing user properties by grabbing them from the first provider, which is Google in your case, and setting them in the user properties for good.
The more complex version of this function, which supports the case of multiple providers, loops through the providers until a DisplayName or a photoURL are found.
Future<void> updateMissingUserPropertise(User user) async {
if (user.photoURL == null) {
user.providerData.forEach((provider) async {
if (provider.photoURL != null) {
await user.updatePhotoURL(provider.photoURL);
return;
}
});
}
if (user.displayName == null) {
user.providerData.forEach((provider) async {
if (provider.displayName != null) {
await user.updateDisplayName(provider.displayName);
return;
}
});
}
}
Upvotes: 0
Reputation: 513
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.getProviderData();
loop through providers and get the desired provider
userData.getProviderId().equals(GoogleAuthProvider.PROVIDER_ID)
Uri photoUrl = userData.getPhotoUrl();
Upvotes: 2