Handling Firebase Insufficient Permissions Errors in Flutter - firebase

How can I handle insufficient permissions errors from firebase? I currently do this:
try {
DocumentSnapshot doc = await Firestore.instance.collection('SomeCollection').document('SomeDocument').get();
// Do something
} catch (error) {
print('Error: $error');
// Do something to show user
}
How ever I can't check for only Permission Errors. Sho how can I catch only insufficient permission errors?
Also when should I use .catchError(), I tried this:
DocumentSnapshot doc = await Firestore.instance.collection('Some Collection').document('Some Document').get().catchError((onError) {
// What to do here
});
I doens't seem to really catch a error, because the exception is still thrown

This is supposed to work
DocumentSnapshot doc = await Firestore.instance.collection('Some Collection').document('Some Document').get().catch((err)=>print(err));

You can recognize the permission error by the error code (which is 'permission-denied').
If it's a different error, you can throw it, or handle diffrently.
try {
DocumentSnapshot doc = await Firestore.instance.collection('SomeCollection').document('SomeDocument').get();
// Do something
} catch (error) {
if (error.code === 'permission-denied') {
// Do something to show user
}
else {
throw new Error(e); // Or do other things
}
}

Related

how to get Firebase Firestore exception code on Flutter?

from the documentation in here it seems that Firestore have some error codes. how to catch that in Flutter so I can localize the error message
I have tried to use the code below
Future<User?> getUser({required String userID}) async {
try {
final documentSnapshot = await _db.collection(path).doc(userID).get();
if (documentSnapshot.exists) {
return User.fromFirestore(documentSnapshot.data()!);
} else {
return null;
}
} on FirebaseFirestoreException (error) {
print(error.code);
// I hope I can get the error.code in here
}
}
but I have error
_db.collection(path).doc(userID).get()
.then((e){
User user = User.fromFirestore(e.data()!);
}).catchError((err)=> print(err.message));

How to catch StorageException in flutter

I'm using Firebase storage with flutter. If the upload operation fails for whatever reason (e.g. exceeds size limits set in console), it causes a StorageException.
I want to do something like this:
try {
final uploadTask = ref.putFile(docFile);
taskSnapshot = await uploadTask.onComplete;
} on StorageException catch (err) {
// Do something
}
But there isn't any StorageException type and I can't find a way to catch any and all exceptions. Any ideas?
You can do something like the following instead.
import 'package:firebase_core/firebase_core.dart' as firebase_core;
try {
final uploadTask = ref.putFile(docFile);
taskSnapshot = await uploadTask.onComplete;
} on firebase_core.FirebaseException catch(e) {
if (e.code == 'permission-denied') {
/// Real permisssion-denied handling
print('User does not have permission to upload to this reference.');
}
if (e.code == 'the-error-code-printed-to-console') {
///the-error-code-printed-to-console handling
print('printing what you want');
}
}
This handles errors and checks if it's due to permission. If you are looking for another cause, you can just print the e.code to the console first, copy the code and check if the code copied previously from console is equal to e.code.
try catch doesnt work very well, I solved it like this:
}, onError: (e) {
debugPrint('Exception::: ==========>>>>>>> ${e.toString()}');
});
It get it that way

Flutter: PlatformException thrown by FireBase won't get caught

I have a function that is used to sign in to Firebase using firebase_auth, however, whenever an exception is thrown it isn't getting caught and still appears in the Android Studio console nor do the print statements in the catch block ever run.
How do I fix this?
signIn({String email, String password}) {
print('listened');
try {
FirebaseAuth.instance.signInWithEmailAndPassword(
email: email, password: password);
}
on PlatformException catch (signUpError) {
print(signUpError.code);
if (signUpError.code == 'ERROR_WEAK_PASSWORD') {
print('Weak Password');
}else if(signUpError.code=='ERROR_USER_NOT_FOUND'){
print('Invalid Username');
}
else{
print(signUpError.toString());
}
}
}
signInWithEmailAndPassword returns a Future<AuthResult> (it is asynchronous), therefore you need to use the catchError method to catch the error when calling an asynchronous method:
FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password).then((result) {
print(result);
})
.catchError((error) {
print("Something went wrong: ${error.message}");
});
Check the following:
https://api.dart.dev/stable/2.3.0/dart-async/Future/catchError.html
https://medium.com/firebase-tips-tricks/how-to-use-firebase-authentication-in-flutter-50e8b81cb29f
The try catch blocks will work if the Firebase call is within an async function and the await statement is used when calling Firebase.
For example, in the following code an error getting the token will be trapped by the on PlatformException catch (... block but an error writing the token to FB RTDB won't be:
Future<void> _saveDeviceToken() async {
try {
final _currentUser = _firebaseAuth.currentUser;
final fcmToken = await _firebaseMessaging.getToken();
if (fcmToken != null) {
// Save the token to Firebase - NO AWAIT STATEMENT
globals.firebaseDatabase
.reference()
.child("pushTokens")
.child("${_currentUser.uid}")
.set({"token": fcmToken});
}
} on PlatformException catch (error, stackTrace) {
print("error: $error");
}
}
whereas adding the await statement, as in the following code, will trap errors in writing to FB RTDB as well:
Future<void> _saveDeviceToken() async {
try {
final _currentUser = _firebaseAuth.currentUser;
final fcmToken = await _firebaseMessaging.getToken();
if (fcmToken != null) {
// Save the token to Firebase - AWAIT STATEMENT ADDED
await globals.firebaseDatabase
.reference()
.child("pushTokens")
.child("${_currentUser.uid}")
.set({"token": fcmToken});
}
} on PlatformException catch (error, stackTrace) {
print("error: $error");
}
}
If you don't want to or can't use await then, as per Peter's answer, the solution is to use the catchError statement instead of try catch.

TypeError: Cannot read property 'native' of undefined

I am implementing firebase phone number authentication in React Native app. I am following this documentation:
https://invertase.io/oss/react-native-firebase/v6/auth/phone-auth
This successfully runs:
const {confirm} = await firebase.auth().signInWithPhoneNumber(value);
this.setState({confirm})
console.log(confirm) // is a function
Now when I run confirm(code):
try {
await this.state.confirm('123456');
// Successful login - onAuthStateChanged is triggered
} catch (e) {
console.error(e); // Invalid code
}
It gives the following error:
TypeError: Cannot read property 'native' of undefined.
I have searched a lot, but couldn't solve it. Please help.
Please do like something
this.state = {confirmResult: null};
Then
const confirmResult = await firebase.auth().signInWithPhoneNumber(value);
this.setState({confirmResult});
And Then
const { confirmResult } = this.state;
try {
await confirmResult.confirm('123456');
// Successful login - onAuthStateChanged is triggered
} catch (e) {
console.error(e); // Invalid code
}
You have now assigned a function from a variable but are running it from a status value. Run on a variable.
try {
await confirm('123456'); // User entered code
// Successful login - onAuthStateChanged is triggered
} catch (e) {
console.error(e); // Invalid code
}

How do I tell the difference between exceptions in flutter authenticating with Firebase?

I have Firebase a sign in for my app. I want to report exceptions to the user so he can correctly login. It is email and password sign in signInWithEmailAndPassword(_email, _password). Testing I can create two exceptions which are self explanatory
1/ Error: PlatformException(exception, There is no user record corresponding to this identifier. The user may have been deleted., null)
2/ Error: PlatformException(exception, The password is invalid or the user does not have a password., null)
I'm using a try catch block to catch the error. Here is my code:
void validateAndSubmit() async {
FocusScope.of(context).requestFocus(new FocusNode());
if (validateAndSave()) {
try {
var auth = AuthProvider.of(context).auth;
FirebaseUser user =
await auth.signInWithEmailAndPassword(_email, _password);
print('Signed in: ${user.uid}');
Navigator.pop(context);
widget.loginCallback(user);
} catch (e) {
print('Error: $e');
setState(() {
_showMessage=true;
});
}
}
}
I want to give a different message depending on the exception. But there doesn't seem to be any code associated with the exception.
You can catch different kind of exceptions, for each exceptions, you can check the code
void validateAndSubmit() async {
FocusScope.of(context).requestFocus(new FocusNode());
if (validateAndSave()) {
try {
var auth = AuthProvider.of(context).auth;
FirebaseUser user =
await auth.signInWithEmailAndPassword(_email, _password);
print('Signed in: ${user.uid}');
Navigator.pop(context);
widget.loginCallback(user);
} on FirebaseAuthInvalidUserException catch (e) {
print('FirebaseAuthInvalidUserException: $e');
if (e.code === 'ERROR_USER_NOT_FOUND') {
setState(() {
_showMessage=true;
});
} else {
// do something
}
}
} on FirebaseAuthInvalidCredentialsException catch (e) {
// do something InvalidCredentials
} catch (e) {
// do something else
}
}
You can check e.code.
Check out native firebase documentation. It has values like 'ERROR_USER_NOT_FOUND'

Resources