Flutter - Firebase Authentication with facebook won't save the user information to the database
I almost forgot about this query. I finally solved how to get it work correctly, so I am posting the code below for anyone that wants to use it. Hope it helps!
//Login with Facebook
void signInUsingFacebook() async {
final FacebookLogin facebookLogin = FacebookLogin();
final FacebookLoginResult facebookLoginResult =
await facebookLogin.logIn(['email']);
switch (facebookLoginResult.status) {
case FacebookLoginStatus.loggedIn:
setState(() {
showSpinner = true;
});
// TODO: Handle this case.
FirebaseAuth.instance
.signInWithCredential(
FacebookAuthProvider.getCredential(
accessToken: facebookLoginResult.accessToken.token),
)
.then((user) async {
await _pushNotificationService.initialise();
final graphResponse = await http.get(
'https://graph.facebook.com/v2.12/me?fields=name,picture,email&access_token=${facebookLoginResult.accessToken.token}');
final profile = JSON.jsonDecode(graphResponse.body);
final DocumentSnapshot doc =
await usersRef.document(user.user.uid).get();
//Storing the user data in the firestore database
if (!doc.exists) {
final userDetails = await Navigator.push(
context, MaterialPageRoute(builder: (ctx) => CreateAccount()));
_db.collection("users").document(user.user.uid).setData({
"username": userDetails[0],
"displayName": userDetails[1],
"email": profile['email'],
"photUrl": "N/A",
"gender": userDetails[2],
"timestamp": timestamp,
"signin_method": 'Facebook',
"location": userDetails[4],
"uid": user.user.uid,
"points": 0,
"bio": userDetails[3],
});
}
setState(() {
showSpinner = false;
});
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => UserProfile(),
),
);
});
break;
case FacebookLoginStatus.cancelledByUser:
// TODO: Handle this case.
setState(() {
showSpinner = false;
});
break;
case FacebookLoginStatus.error:
// TODO: Handle this case.
setState(() {
showSpinner = false;
});
break;
}
}
Explanation: The main difference between the code from the question and answer is this part:
// TODO: Handle this case.
FirebaseAuth.instance
.signInWithCredential(
FacebookAuthProvider.getCredential(
accessToken: facebookLoginResult.accessToken.token),
).then((user))async{}
Getting the current user object first and then trying to get the accesstoken for that current user doesn't work on the current version of flutter_facebook_login package.
You have to use the FirebaseAuth.instance.signInWithCredential()
method and use the FacebooAuthProvider().getCredential(accessToken:)
This will let the firebase to sign in with the credentials and return the current user object. Now you can use the current user object to store details to the firestore database.
Note: Facebook returns the user details in JSON format. So you have to decode the JSON data before you can use it. The code to decode the JSON data is below:
final graphResponse = await http.get(
'https://graph.facebook.com/v2.12/me?fields=name,picture,email&access_token=${facebookLoginResult.accessToken.token}');
final profile = JSON.jsonDecode(graphResponse.body);
Hope it will help! CHEERS
hasib_ullah
Simplicity is prerequisite for reliability and I deliver both
Updated on December 19, 2022Comments
-
hasib_ullah over 1 year
I want to let the user sign in with facebook and check if the user already exists in the database or not. If the user(uid) already exists then it should sign in normally but if the user is not in the database then I want to send the user to the create account page. This is my code but it's not working. This lets the user to sign in but is not fetching any data from the user profile, what can I do?
//Login with Facebook void signInUsingFacebook() async { final FacebookLogin facebookLogin = FacebookLogin(); final FacebookLoginResult facebookLoginResult = await facebookLogin.logIn(['email']); switch (facebookLoginResult.status) { case FacebookLoginStatus.loggedIn: // TODO: Handle this case. FirebaseAuth.instance.signInWithCredential( FacebookAuthProvider.getCredential( accessToken: facebookLoginResult.accessToken.token), ); FirebaseUser currentUser = await FirebaseAuth.instance.currentUser(); if (currentUser != null) { print('user is logged in'); await _pushNotificationService.initialise(); final DocumentSnapshot doc = await usersRef.document(currentUser.uid).get(); //Storing the user data in the firestore database if (!doc.exists) { final userDetails = await Navigator.push(context, MaterialPageRoute(builder: (context) => CreateAccount())); _db.collection("users").document(currentUser.uid).setData({ "username": userDetails[1], "displayName": userDetails[2], "email": currentUser.email, "photUrl": userDetails[0], "gender": userDetails[3], "timestamp": timestamp, "signin_method": currentUser.providerId, "location": userDetails[4], "uid": currentUser.uid, "points": 0, "bio": userDetails[5], }); } } break; case FacebookLoginStatus.cancelledByUser: // TODO: Handle this case. print('cancelled by user'); break; case FacebookLoginStatus.error: // TODO: Handle this case. print('login error'); break; }
-
rizerphe almost 4 yearsWhile this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply.
-
hasib_ullah almost 4 yearsThank you for pointing that out. I will definitely add the explanation behind this code.