Flutter Firebase Permission Denied - firebase

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.

Related

Flutter sign in with google lost authentication when the internet connection lost, how to re-auth it?

We are currently building an app that requires only google sign in and communicate with the Firebase depending on those data that we get with sign in.
The problem is this; after logging in to the app if the user lost internet connection and then re-establishes that connection without closing the app, FirebaseAuth.currentUser is not null but at the same time the user is not authenticated so the functions that i need to communicate with the DB is not working.
My question is simply this;
How do i check for the authentication and then re-authanticate the user.
My signin method is below, i tried to re-sign in every time when user enters some certain pages but that just not seemed good but does solves the problem. Is there a optimized way?
Future<String> 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 GoogleAuthCredential credential = (GoogleAuthProvider.credential(
accessToken: googleAuth!.accessToken,
idToken: googleAuth.idToken,
) as GoogleAuthCredential);
// Once signed in, return the UserCredential
final UserCredential? authResult =
await _auth!.signInWithCredential(credential);
final User? user = authResult!.user;
//assert(user!.isAnonymous);
assert(await user!.getIdToken() != null);
final User? currentUser = _auth!.currentUser;
assert(user!.uid == currentUser!.uid);
return 'signInWithGoogle succeeded: $user';
}
Edit:
We were using connectivity_plus plugin so we created a listener for it and if the user changes its connection to wifi or mobile we simply re-signin them. It worked for us it may have work for you as well;
#override
void initState() {
subscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) {
if (result == ConnectivityResult.mobile ||
result == ConnectivityResult.wifi ||
result == ConnectivityResult.ethernet) {
Login().signInWithGoogle();
}
print("${result}");
});
// TODO: implement initState
super.initState();
}
dispose() {
super.dispose();
subscription.cancel();
}
The Flutter Firebase docs have a re-authenticate user option and it sounds quite similar to your situation.
Re-authenticate a user

Flutter Google Sign-in, stuck after selecting account

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.

Flutter Firebase - failing to properly delete a Google authenticated user

I'm trying but failing to re-trigger the authentication steps that the user gets taken through when they authenticate themselves using Google sign-in, following deletion of the user. The deleted user simply gets signed in immediately (instead of being taken through the authentication steps), when using Google sign-in the second time. I want to be able to re-trigger the authentication steps for my own testing purposes.
Specifically, I've got a user who I've authenticated and signed in as per the FlutterFire documentation, i.e.
Future<UserCredential> 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 GoogleAuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
// Once signed in, return the UserCredential
return await FirebaseAuth.instance.signInWithCredential(credential);
}
I then proceed to delete the user; again, as per the FlutterFire documentation, i.e.
try {
await FirebaseAuth.instance.currentUser.delete();
} catch on FirebaseAuthException (e) {
if (e.code == 'requires-recent-login') {
print('The user must reauthenticate before this operation can be executed.');
}
}
That works, insomuch as the user is no longer listed amongst the authenticated users in the Firebase console. However, if I now proceed to call signInWithGoogle() again, then instead of getting taken through the authentication steps again (i.e. being prompted to enter an email, password, etc.), the user simply gets signed in straight away. It's as if the user hasn't been properly deleted. How would I go about re-triggering the authentication steps?
You must also call GoogleSignIn().signOut() after the Firebase sign out or delete.
In my case, I had to reauthenticate firebase user inside the delete functions try-catch as currentUser() always return null AND GoogleSignIn().signOut() didnt work. Maybe a bug.
import 'package:google_sign_in/google_sign_in.dart';
import 'package:firebase_auth/firebase_auth.dart';
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _auth = FirebaseAuth.instance;
//will need to sign in to firebase auth again as currentUser always returns null
//this try-catch block should be inside the function that deletes user
try {
//FirebaseUser user = await _auth.currentUser(); //returns null so useless
//signin to google account again
GoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn();
GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;
//get google credentials
AuthCredential credential = GoogleAuthProvider.getCredential(
idToken: googleSignInAuthentication.idToken,
accessToken: googleSignInAuthentication.accessToken);
//use credentials to sign in to Firebase
AuthResult authResult = await _auth.signInWithCredential(credential);
//get firebase user
FirebaseUser user = authResult.user;
print(user.email);
//delete user
await user.delete();
//signout from google sign in
await _googleSignIn.signOut();
} catch (e) {
print('Failed to delete user ' + e.toString());
}

Flutter Firebase Storage : no auth token for request

I have been trying to upload an image to the Firebase Storage while using the Image_Picker.
When I want to upload the image(imageFile) to Firebase Storage
Future uploadFile() async {
StorageReference storageReference =
storage.ref().child('profile/${Path.basename(imageFile.path)}}');
print('uploading..');
StorageUploadTask uploadTask = storageReference.putFile(imageFile);
//waiting for the image to upload
await uploadTask.onComplete;
print('File Uploaded');
storageReference.getDownloadURL().then((fileURL) {
setState(() {
imageURL = fileURL;
});
print(imageURL);
});
}
However, during the uploading, there is an error mentioning I do not have auth token request.
I have used Firebase Auth before for storing data to the database and everything is configured there properly(I assume so since Firebase gave me a google.json file).
W/NetworkRequest( 5796): no auth token for request
E/StorageUtil( 5796): error getting token java.util.concurrent.TimeoutException: Timed out waiting for Task
I have also tried to change the rules for the storage from read, write if auth != null to read, write.
Check your firebase storage rules. I think that the default option is to allow only authenticated users. If that is the problem simply change them to what suits your needs best.
Are you using GoogleSignIn for authentication and can you provide your user authentication code for firebase i was having same issue "no auth token request" for googlesignin method i resolved by using the following code.
final GoogleSignIn googleSignIn = GoogleSignIn();
FirebaseUser firebaseUser;
GoogleSignInAccount account = await googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await account.authentication;
final AuthCredential _cred = GoogleAuthProvider.getCredential(idToken: googleAuth.idToken, accessToken: googleAuth.accessToken);
final AuthResult _res = await FirebaseAuth.instance.signInWithCredential(_cred);
firebaseUser = _res.user;

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