Flutter Google Sign-in, stuck after selecting account - firebase

I am running into issue trying to signin to Firebase with Google Sign-in in my Flutter app.
I've seen two other posts about this, but no answers that resolve it for myself. I am using Google Sign-in provider in flutter, google_sign_in: ^5.1.0, Flutter ver 2.2.1
I have followed the instructions on generating/adding the Sha-1, Sha-256 keys to my firebase project. Prior to that , I was getting an API exception. I added the keys, downloaded the latest google-json file to my android folder and got beyond that error. Now, when I click to Sign-in, I get the account selection screen.
I select my account, and then I hit a white page with endless spinner.
Here is the login code I'm running.
GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: <String>[
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);
Future<void> _handleGoogleSignIn() async {
try {
GoogleSignInAccount? googleSignInAccount =
await _googleSignIn.signIn();
GoogleSignInAuthentication? googleSignInAuthentication =
await googleSignInAccount?.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleSignInAuthentication?.accessToken,
idToken: googleSignInAuthentication?.idToken,
);
final UserCredential user = await _auth.signInWithCredential(credential);
} catch (error) {
print('in error block');
print(error);
}
}
In doing some debug, it doesn't seem to get beyond the initial line:
GoogleSignInAccount? googleSignInAccount =
await _googleSignIn.signIn();
But I don't get any error, any warning, nothing...just a spinner that sits indefintely.
Any ideas on how to solve this, or at minimum , debug this without getting an error?
Thx

After digging further, I found he answer on the same bug reported on the Flutter github account.
https://github.com/flutter/flutter/issues/89169
The solution:
In the following code snippet (which is defined as default setup)
GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);
Change https://www.googleapis.com/auth/contacts.readonly (restricted scope) to https://www.googleapis.com/auth/userinfo.profile (non-restricted scope).
After that, OAuth screen will proceed with sign in.

Related

Flutter Firebase Permission Denied

After i sign out, i try to log in again, yes it logs in succesfully but the problem is, i start to get error [cloud_firestore/permission-denied] but when i restart my application, it works again well. What am i missing?
PS: im logging in with Google.
This is my log in code:
Future signInWithGoogle() async {
// Trigger the authentication flow
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
// Obtain the auth details from the request
final GoogleSignInAuthentication googleAuth =
await googleUser!.authentication;
// Create a new credential
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
// Once signed in, return the UserCredential
await _auth.signInWithCredential(credential);
}
This is my sign out code:
await _googleSignIn.signOut().then((value) async {
await widget.firebaseAuth.signOut().then((value) {
Navigator.pop(context);
});
}).onError((error, stackTrace) {
print(error);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text("ERROR!! TRY AGAIN"),
));
});
The cloud_firestore/permission-denied error comes from Firestore (the database), not from Firebase Authentication.
Most likely you have some realtime listeners in your code that require the user to be signed in, and those get rejected by the database once you sign the user out.
You can either remove the listeners by canceling the subscriptions, or you can ignore the errors, as the listeners are also canceled automatically after this error occurs.
In my case, I forgot to activate "google-sign in" as an authentication method in firebase.

Firebase IdToken generated using FirebaseAuth.currentUser.getIdToken() on flutter gives error "failed to verify token signature" on Go backend

I am working on a flutter app where after sign-in, I have to validate a user's idToken on a custom backend (written in Go) using the Firebase admin SDK: firebase.google.com/go.
I am using the following snippet to sign-in the user via GoogleSignIn and retrieve the Firebase idToken on the client side:
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
Future<String> signInWithGoogle() async {
await Firebase.initializeApp();
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleSignInAuthentication.accessToken,
idToken: googleSignInAuthentication.idToken,
);
final UserCredential authResult = await _auth.signInWithCredential(credential);
final User user = authResult.user;
String FirebaseIdToken = await _auth.currentUser.getIdToken();
print("FirebaseIdToken: " + FirebaseIdToken);
if (user != null) {
/* code to validate user and return it */
} return null;
}
I copy the token corresponding to the FirebaseIdToken variable and send it to the backend using Postman with a Authentication: Bearer <token> request header.
At the backend, there is the following:
/* am.cli here is basically the auth.Client in firebase admin SDK and clientToken is the token received from flutter app. */
idToken, err := am.cli.VerifyIDToken(context.Background(), clientToken)
log.Println("ERROR:", err)
I get the following error printed:
ERROR: failed to verify token signature
Based on the documentation for both client & backend, I believe that I'm using the correct methods to retrieve and to verify the token.
I have tried to retrieve the idToken with the following code as well:
IdTokenResult idTokRes = await _auth.currentUser.getIdTokenResult(true);
print("idTokRes: " + idTokRes.token);
But this fails the same way. (And idTokRes.token and the FirebaseIdToken from the previous method are not same.)
I have also tried to verify the token manually on https://jwt.io/ with the public certificate and the private key which fails as well.
Any help would be appreciated!
Thanks to a member of the Flutter community, I was able to solve the problem.
Turns out, for some reason, the FirebaseIdToken printed by
print("FirebaseIdToken: " + FirebaseIdToken);
is not the complete token. Because of being large, the output gets truncated.
(Still not sure why though. Does Dart's print() statement truncate large strings?)
Edit: Apparently, its the terminal window that truncates/wraps a large output by embedding linebreaks to it.
But, by using the following snippet
String firebaseIdToken = await user.getIdToken();
while (firebaseIdToken.length > 0) {
int startTokenLength =
(firebaseIdToken.length >= 500 ? 500 : firebaseIdToken.length);
print("TokenPart: " + firebaseIdToken.substring(0, startTokenLength));
int lastTokenLength = firebaseIdToken.length;
firebaseIdToken =
firebaseIdToken.substring(startTokenLength, lastTokenLength);
}
I was able to print the complete token in 3 broken parts, which I then concatenated, and sent to the backend via Postman and got no errors this time.
Thanks Rexford!

Flutter Google Login not Getting Registered in Firebase

1. The Problem
I'm trying to implement simple Facebook and Google Sign-in buttons with Firebase and Flutter, however the Google version is acting very weird. When I print the FirebaseAuth.instance.currentUser() I either get errors or prior Facebook login data.
When I login with Facebook, my account does appear on Firebase, however, the Google login seems to do nothing.
Is this something I messed up in the code below or some incompatibility problem with AndroidX with parts of these libraries? Something else?
Also, it is not very clear to me if I have to put the Project public-facing name somewhere inside my project to make the integration with Firebase work (I had to do something similar to setup the Facebook Login button).
2. The Facebook Login
I had to replace logInWithReadPermissions with signInWithCredential because recent versions have changed their API. I've also tried to use previous versions of the packages, but encountered many errors (probably due to AndroidX):
final _auth = FirebaseAuth.instance;
Future<FirebaseUser> _loginWithFacebook () async {
final facebookLogin = FacebookLogin();
final result = await facebookLogin.logInWithReadPermissions(['email']);
if (result.status == FacebookLoginStatus.loggedIn){
final FacebookAccessToken accessToken = result.accessToken;
AuthCredential credential = FacebookAuthProvider.getCredential(
accessToken: accessToken.token,
);
AuthResult signInResult = await _auth.signInWithCredential(credential);
FirebaseUser fbUser = signInResult.user;
return fbUser;
}
else{
return null;
}
}
3. The Google Login
Again, signInWithCredential seems to be the more recent API:
Future<FirebaseUser> _loginWithGoogle () async{
final GoogleSignIn _googleSignIn = GoogleSignIn();
GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
AuthResult signInResult = await _auth.signInWithCredential(credential);
final FirebaseUser user = signInResult.user;
print(user);
return user;
}
Edit
I've tried it on an Android 9.0 (Pie) emulator and it still doesn't work.
Apparently, my authentication code was correct for both Google and Facebook, considering the most up-to-date API.
However I needed to integrate a SHA1 Fingerprint to my Firebase environment, which is something I didn't realize I needed to do because none of the tutorials I followed mentioned it and it can be easily dismissed when enabling the Google Sign-in method inside Firebase.
Anyway, here are the steps you will need to complete to get the SHA1 Fingerprint:
Open Command Prompt and cd C:\Program Files\Android\Android Studio\jre\bin.
Get the SHA1 key:
keytool -list -v -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore
Go to Firebase Console > Project settings > Add Key and add the key.

Flutter Firebase Auth / Google_sign_in fail to login with statuscode=CANCELED

This is my pubspec.yaml. I'm using Flutter:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
shared_preferences: ^0.4.2
json_serializable: ^1.2.1
camera: ^0.2.3
path_provider: ^0.4.1
simple_permissions: ^0.1.6
share: ^0.5.3
#Google Sign_In
firebase_auth: ^0.5.20
google_sign_in: ^3.0.5
I cannot authenticate with the Google Sign In method. The window shows up normally and after my app throws a error:
PlatformException(sign_in_failed, Status{statusCode=CANCELED, resolution=null}, null)
Haven't found any solutions online, can someone help me out?
The following is my _signIn() method
Future<FirebaseUser> _signIn() async {
GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
GoogleSignInAuthentication gSA = await googleSignInAccount.authentication;
FirebaseUser user = await auth.signInWithGoogle(
idToken: gSA.idToken, accessToken: gSA.accessToken);
print("User Name : ${user.displayName}");
return user;
}
My code crashes after I call GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn(); so my guess was, that my setup was wrong.
This is how I call the _signIn()
MaterialButton(
child: Text("Google Sign-In"),
onPressed: (){
_signIn()
.then((FirebaseUser user) => print(user))
.catchError((e) => print(e));
},
),
I already deleted the Firebase-Project on the google dev console online and created a new one. Also I tried the anonymous login -> worked fine
Any help is appreciated
I just ran into the same issue.
This is how I solved it.
1) Get your SHA1 certificate key. (see https://developers.google.com/android/guides/client-auth)
2) Place the SHA1 key in your Firebase console
3) Rebuild your flutter App and try again. It should be working now.
Okay, so I managed to fix this problem with using a APK in release mode!
What you have to do:
Build your app in release mode and add the SHA1 or SHA256 to your firebase project.
If you don't know how to prepare your app for release you can do this quickly.

Sign In Google will stuck on black screen when try to Add Users Flutter

Hi so i try to add firebase auth on my app, so i followed the documentations in here https://pub.dartlang.org/packages/firebase_auth from the plugin creators it self, It works well at first, but then i'm just ecounter an error or bug, its when i'm tried to add users instead of choose users that already login in my device, after add the users it will stuck forever in black sreen like the picture above, it not giving some error message it just stuck there. So is there anyone that already has same issues like me ? is there any solutions for this ? here is my code for handle the sign in
Future<FirebaseUser> _handleSignIn() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
GoogleSignInAccount googleUser = await _googleSignIn.signIn();
GoogleSignInAuthentication googleAuth = await googleUser.authentication;
FirebaseUser user = await _auth
.signInWithGoogle(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
Navigator.of(context).pushReplacementNamed('/HomeScreen');
await prefs.setString('accesToken', googleAuth.accessToken);
await prefs.setString('email', googleUser.email);
await prefs.setString('displayName', googleUser.displayName);
await prefs.setString('photoUrl', googleUser.photoUrl);
return user;
}
Most probably this happens because you have not enabled the Sign-in Method in Firebase Console.
Just enable Required Sign-in Methods and it should work fine.

Resources