I keep getting a null email whenever I sign in with Apple. Note that the display name is not null. Also, I've made sure to revoke any tokens before trying to Sign in with Apple again because as per my understanding, Apple only provides the email once, in the initial sign-up. Here is my code for signing in with Apple in Android with Firebase:
The OAuth provider:
fun appleOAuthProvider(appLanguage: String): OAuthProvider {
return OAuthProvider
.newBuilder("apple.com")
.setScopes(listOf("name", "email"))
.addCustomParameter("locale", currentLanguageLocale(appLanguage))
.build()
} //: FUN
Signing in:
private fun singInUser(
auth: FirebaseAuth,
context: Context,
appLanguage: String,
isSigningIn: MutableState<Boolean>,
completion: (FirebaseUser?) -> Unit
) {
auth
.startActivityForSignInWithProvider(context.getActivity(), HelperFunctions.appleOAuthProvider(appLanguage))
.addOnSuccessListener { authResult ->
Log.d("SIGN IN WITH APPLE", "activitySignIn:onSuccess:${authResult.user}")
completion(authResult.user)
} //: ON SUCCESS
.addOnFailureListener { e ->
Log.w("SIGN IN WITH APPLE", "activitySignIn:onFailure", e)
isSigningIn.value = false
completion(null)
} //: ON FAILURE
} //: FUN
After signing in, I collect the user's data with the authResult.user I previously got:
private fun collectDataFromApple(
user: FirebaseUser?,
completion: (SignInResult) -> Unit
) {
val uid = user?.uid
val email = user?.email
var firstName = separatedFullName(user?.displayName)?.get(0)
var lastName = separatedFullName(user?.displayName)?.get(1)
if (firstName.isNullOrEmpty()) {
firstName = lastName
} else if (lastName.isNullOrEmpty()){
lastName = firstName
}
completion(
SignInResult(
data =
UserData(
personalInformation = UserData.PersonalInformation(
userID = uid,
email = email,
firstName = firstName,
lastName = lastName,
imageBitmap = null,
isNewUser = true,
isEmailVerified = mutableStateOf(true),
firebaseHasData = false
),
addressInformation = UserData.AddressInformation(),
contributeStatistics = UserData.ContributeStatistics()
),
errorMessage = null
)
)
} //: FUN
The user?.email returns null for an unknown reason. The firstName and lastName are not null, however. Why is that?
When you authenticate your users in Firebase using the Facebook provider, the email address of the user is not present inside the FirebaseUser object. So to solve this, you have to read the list of providers and get the second provider as in the following lines of code:
The FirebaseUser#getProviderData() method returns an object of type UserInfo which:
Typically, the first element (index 0) in the
providerDatalist corresponds to the user's primary authentication provider which is Google, and the second element (index 1) corresponds to the secondary provider, which, in this case, is Apple, in your use-case.If you want to have the email present inside the FirebaseUser object as well, then I recommend you update the object using FirebaseUser#updateEmail(email).