I'm using firebase in Android Studio with kotlin.
I want to know whether login account is email-register account or google social account.
As I know, if FirebaseAuth.getInstance().currentUser.providerId is "google.com", user used google social login.
And if providerId is "password", user used email register with firebase.
But only I can get "firebase" from providerId.
How can I solve it?
It it is neccessary for making login function.
I can get only "firebase" from providerId.
According to the API documentation, getProviderId() (or just providerId for Kotlin) will always return FirebaseAuthProvider#PROVIDER_ID (which is equal to "firebase").
If you want to determine which authentication channel was used to get this Firebase ID Token, you need to use getProviderData() which contains the UserInfo objects returned from the social logins.
val auth = FirebaseAuth.getInstance();
val hasLinkedGoogleUser = auth.providerData.any{ it.providerId == GoogleAuthProvider.PROVIDER_ID }
Related
in the following code:
private val auth: FirebaseAuth
val authResult = auth.signInWithCredential(googleCredential).await()
val isNewUser = authResult.additionalUserInfo?.isNewUser ?: false
What does the isNewUser variable tell us? Does it tell us that the user is new to my app/my app's firestore database? Or, does it tell us whether the user is new to firestore authentication in general? More specifically, can this variable be used to check if the user exists in my app's firestore database?
I found this code snippet in an article that explains how to implement firestore in jetpack compose. My interpretation of the code that the author wrote implies that this value can be used to check if the user is new to my app (in the article, the author calls a method that adds the user to their firestore database if and only if the isNewUser value returns false).
If isNewUser is true, that means the user has logged in to your application ("Firebase Project") for the first time i.e. created a new account with Google or any OAuth provider. This is useful because unlike email password authentication that has separate signInWithEmailAndPassword() and createUserWithEmailAndPassword(), OAuth providers just have signInWithCredential() (or popup/redirect on web).
Firebase Authentication is a different product and has nothing to do with Firestore. They can be used individually.
I have the possibility that the user can choose if they want to log in with Google, Facebook, email/password, etc.
After testing my app, the following happened:
I sign up with my name, email, and password
Handle the get started logic
Verify my auth users on Firebase (grey email icon)
Sign out of the account
Now, I want to log in with Google (same email used on the sign-up with email and password)
The Google sign-in worked
Verify my auth users on Firebase (the grey email icon changed into the Google one)
Sign out of the account
Can't log in with email and password anymore but the google sign in worked
After some research, I end up with the Link Multiple Auth Providers to an Account on Android documentation
I realized I have to refactor my code to not use the FirebaseAuth.signInWith methods
This is a little except of my loginEmailAndPassword:
val credential = EmailAuthProvider.getCredential(email, password)
firebaseAuth.currentUser!!.linkWithCredential(credential).addOnCompleteListener{ authTask: Task<AuthResult> ->
if (authTask.isSuccessful) {
I have an 'else' meaning the (authTask.isSuccessful) did not happened and another 'if' with the FirebaseAuthUserCollisionException
val exception: java.lang.Exception? = authTask.exception
if (exception is FirebaseAuthUserCollisionException) {
linkAndMerge(credential)
My goal is to link and merge, and I do not know how to link the accounts (both email grey and Google on Firebase)
private fun linkAndMerge(credential: AuthCredential) {
val authenticatedUserMutableLiveData: MutableLiveData<ResponseState<UserModel>> =
MutableLiveData()
val prevUser = firebaseAuth.currentUser
firebaseAuth.signInWithCredential(credential)
.addOnSuccessListener { result ->
val currentUser = result.user
// Merge prevUser and currentUser accounts and data
// ...
}
.addOnFailureListener {
authenticatedUserMutableLiveData.value = ResponseState.Error("Error")
}
}
My questions:
Can I call something to merge prevUser and currentUser accounts. I just want to the user have the possibility of using different authentications.
I am not worried about the data because if it's the same User UID does not matter if the authentication provider
Can I still use 'createUserWithEmailAndPassword'?
Steps 1 to 9 provide the expected behavior. If you create a user with email and password and right after that you sign in with Google, the account will only be accessible with Google. Why? Because behind the scenes Firebase converts the account that was created with email and password into an account with the Google provider. Unfortunately, you cannot reverse that change.
The link in your question, is referring to the possibility to link an existing account to a specific provider. For example, if you implement anonymous authentication, then you can link that account with Google, for example. This means that the UID remains the same.
If you want to stop that mechanism from happening, then you should consider allowing the creation of different accounts for different providers. You can find this option which is called "Create multiple accounts for each identity provider" right inside the Firebase Console, in the Settings tab inside the Authentication.
I am implementing sign in with Apple. I can successfully see the Apple login page. I key in the correct credentials. It should be able to sign in/sign up to the firebase based on the returned value from Apple.
However I am getting this error Error: The supplied auth credential is malformed, has expired or is not currently supported. Something must be wrong at the firebase side? You may refer to the onPressAppleLogin function below on the logic. Many thanks!
What I have done:
In Firebase
Authentication with Sign-in provider Apple enabled
My service id is co.myexampleapp.signinwithapple
My authorization callback is https://my-example-app.firebaseapp.com/__/auth/handler
In developer.apple.com
I created a service id co.myexampleapp.signinwithapple with the service Sign In with Apple enabled
I added my-example-app.firebaseapp.com for the Domain and https://my-example-app.firebaseapp.com/__/auth/handler in the Return URLs
My React Native source code
import { appleAuthAndroid } from '#invertase/react-native-apple-authentication';
import firebase from 'react-native-firebase'
getRandomString = (length: any) => {
let randomChars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let result = ''
for (let i = 0; i < length; i++) {
result += randomChars.charAt(Math.floor(Math.random() * randomChars.length))
}
return result
}
onPressAppleLogin = async () => {
const rawNonce = this.getRandomString(20);
const state = this.getRandomString(20)
appleAuthAndroid.configure({
clientId: 'co.myexampleapp.signinwithapple',
redirectUri: 'https://my-example-app.firebaseapp.com/__/auth/handler',
responseType: appleAuthAndroid.ResponseType.ALL,
scope: appleAuthAndroid.Scope.ALL,
nonce: rawNonce,
state,
});
const response = await appleAuthAndroid.signIn();
const appleCredential = await firebase.auth.AppleAuthProvider.credential(response.id_token, rawNonce)
const appleUserCredential = await firebase.auth().signInWithCredential(appleCredential) // error happens here!
}
This is 100% due to the wrong Services ID on the server or the client.
I was working on a project in which we have Django as the backend server the backend developer used a different Services ID on the server & I on the client-side used a different Services ID.
How we solved this issue.
Open the Firebase console in the general settings check the bundle ID of the ios app compare it with the bundle ID in your Xcode. Make sure the Services is ID is correct and you have the latest provisioning profile with the Services Id added inside it.
Read this article to understand how to create a service ID. https://firebase.google.com/docs/auth/android/apple?authuser=4
You need to add the same services ID that you created above in the firebase console where you enable apple auth service in the authentication section
In your case you need to add service id
co.myexampleapp.signinwithapple
in the input box that is shown in the screenshot.
There is some sort of error in initializing the credentials.
Three types of errors may occur:
In the response, the token may be get expired. In that time you can use refresh token function to get new token.
Have a look at the rules in the firebase, if you initialized your app in the locked mode read and write will be set to false. If it so, change it to true.
Check whether you have enabled Api keys.
Important Check whether you enabled the third party access for the Apple Id.
Since the problem is with token, I suggest you to check the following.
Make sure you provided your email in support email in firebase project settings.
Try logging out before performing signing in operation. Due to improper logout during development this may happen.
Make sure you always logout before signin. Helped me in some cases.
Device time - since the token generated will be based on timestamp.
I am having trouble integrating LinkedIn authorization from OAuth .io with Firebase on Android.
I am able to authenticate my user through LinkedIn, and OAuth .io is able to save the token into the Firebase database (on the application table not the system table, yet).
But when I pass the received token to Firebase as shown on the code below, firebase replies with an error.
oauth.popup("linkedin2", new OAuthCallback() {
#Override
public void onFinished(OAuthData data) {
String token = data.token;
FirebaseAuth.getInstance().signInWithCustomToken(token);
}
The error I get is:
com.google.firebase.auth.FirebaseAuthInvalidCredentialsException: The
custom token format is incorrect. Please check the documentation.
How can I make this work?
Just a suggestion, why dont you do the normal authentication with either
Facebook TwitterGitHubPersonaEmail/Password
And then after successful signing ask the user to retrieve their data by signing in to their linkedIn account.
I am using socialauth android for my app. My requirement is to reuse the access token keys and secret previously stored during the authorisation. I am unable to do it in any possible way, even I googled a lot but could not find any way resusing the access tokens for Facebook, twitter, g+ etc. to avoid reauthorisation and reauthentication for next time.
I am getting the token as follows
String token=adapter.getCurrentProvider().getAccessGrant().getKey()
Storing this token in database and I want to use nexr time when user tries to login agsin to avoid the process of re authentication and instead directly user must be able to use this token to perform updatestatus and other functions.
How can I do this?
You can try the following
val socialAuthManager = new SocialAuthManager
socialAuthManager.setSocialAuthConfig(socialAuthConfig)
val providerId = "linkedin"
val linkedinAccessToken = YOUR_TOKEN
val accessGrant = new AccessGrant();
accessGrant.setKey(linkedinAccessToken);
accessGrant.setProviderId(providerId);
AuthProvider provider = socialAuthManager.connect(accessGrant);
Profile profile = provider.getUserProfile();