How to delete specific data from firebase - firebase

I'm trying to implement a function that deletes specific data (based on id) from the server.
My function looks like this:
Future<bool> deleteData(int index) {
_data.removeAt(index);
notifyListeners();
return http
.delete(
'https://*my address*/${_data[index].id}.json')
.then((http.Response response) {
return true;
}).catchError((error) {
print(error);
return false;
});
}
The data is deleted locally, but not deleted on the server.
Instead I get this error:
I/flutter ( 5517): ══╡ EXCEPTION CAUGHT BY GESTURE
╞═══════════════════════════════════════════════════════════════════
I/flutter ( 5517): The following RangeError was thrown while handling
a gesture: I/flutter ( 5517): RangeError (index): Invalid value: Valid
value range is empty: 0

I found a solution to my problem -
Future<bool> deleteData(int index) {
selectedDataId = _data[index].id //new line
_data.removeAt(index);
notifyListeners();
return http
.delete(
'https://*my address*/${selectedDataId}.json')
.then((http.Response response) {
return true;
}).catchError((error) {
print(error);
return false;
});
}
Because i deleted my data locally, i needed to stroe it before in var and then use this var

Related

Unable to use a Callable Cloud Function in Flutter

I'm currently using a Firebase Cloud Function, which I wish I can use on Call to check if an Image has adult content, and see some of the tutorials out there I manage to create this function:
exports.checkImage = functions.https.onCall(async (data, context) => {
const img_base64 = data;
const request = {
image: {
content: img_base64
}
};
try {
const [result] = await client2.safeSearchDetection(request);
console.log(result.safeSearchAnnotation?.adult);
return result.safeSearchAnnotation?.adult;
} catch (error) {
console.log(error);
return;
}
return;
});
Now I'm tried to send the Image using an iOS Emulator with that call Function in 2 ways:
First Option I tried:
1.
exports.checkImage = functions.https.onCall(async (data, context) => {
const img_base64 = data;
const request = {
image: {
content: img_base64
}
};
try {
const [result] = await client2.safeSearchDetection(request);
console.log(result.safeSearchAnnotation?.adult);
return result.safeSearchAnnotation?.adult;
} catch (error) {
console.log(error);
return;
}
return;
});
The problem here is I get this Error on my Debugging Console:
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: MissingPluginException(No implementation found for method FirebaseFunctions#call on channel plugins.flutter.io/firebase_functions)
#0 convertPlatformException (package:cloud_functions_platform_interface/src/method_channel/utils/exception.dart:16:5)
#1 MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:39:13)
<asynchronous suspension>
#2 HttpsCallable.call (package:cloud_functions/src/https_callable.dart:35:37)
<asynchronous suspension>
#3 DatabaseMethods.clearImage
package:property1/providers/database.dart:294
In someplace I read that the onCall Cloud Functions can be use as regular End Points so I did this:
clearImage(imageX) async {
final url = Uri.parse(
'https://us-central1-XXXXXXX-XXXX.cloudfunctions.net/checkImage',
);
try {
final response = await http.post(
url,
body: json.encode({
"image": {
"content": imageX
}),
);
}
}
In this one, I only get an Invalid Request unable to process.
I even try this from Postman getting the same result bad request.
As additional data I call this function from where I select the Image with this code:
void _pickImage() async {
final imagePicker = ImagePicker();
final pickedImageFile = await imagePicker.getImage(
source: ImageSource.gallery,
imageQuality: 50,
);
setState(() {
if (pickedImageFile != null) {
_pickedImage = File(pickedImageFile.path);
}
});
// This section will be used to check the Images with Google Vision.
List<int> imageBytes = _pickedImage.readAsBytesSync();
String base64Image = base64Encode(imageBytes);
DatabaseMethods().clearImage(base64Image);
widget.imagePickFn(File(pickedImageFile.path));
}
Basically, I convert the image to a Base64 encoded image that I send so Cloud Vision could work with it.
I even try to just check if I get to the Cloud Function by Commenting out the try of Cloudvision and just adding a console log to get what data is receiving but it is never reached, always an Invalid request, unable to process is what I get.
Any ideas on why I'm not reaching the Function, or on how I can test this from my iOS Emulator.
Kind Regards,
For calling onCall cloud functions from flutter apps, you have to use FirebaseFunctions.instance.httpsCallable():
import 'package:cloud_functions/cloud_functions.dart';
try {
final result =
await FirebaseFunctions.instance.httpsCallable('checkImage').call();
} on FirebaseFunctionsException catch (error) {
print(error.code);
print(error.details);
print(error.message);
}
First, install the package:
flutter pub add cloud_functions
Here's the documentation.

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));

Why My Update Email is not WORKING, Firebase and Flutter?

I want to build a function that update the user email in firebase so this is what I did:
1- checked if there is internet.
2- do user.updateEmail with the email I got from firestore after I uploaded it in the sign Up and It can't be null because I used it down and it also prints the error :
NoSuchMethodError: The method 'updateEmail' was called on null.
I/flutter ( 9769): Receiver: null
I/flutter ( 9769): Tried calling: updateEmail("omarkaram1st#gmail.com")
see It got the email but somehow it can't send an email;
Code :
switchAccount() async {
try {
final user = await _auth.currentUser();
final result = await InternetAddress.lookup('google.com');
try {
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
user.updateEmail(email);
AwesomeDialog(
btnOkText: 'Ok',
context: context,
headerAnimationLoop: false,
dialogType: DialogType.INFO,
animType: AnimType.BOTTOMSLIDE,
title: 'Info',
desc: 'A Reset Email Has Been Sent To $email',
btnOkOnPress: () {},
)..show();
}
} catch (e) {
print(e);
}
} on SocketException catch (_) {
AwesomeDialog(
btnOkText: 'Retry',
context: context,
headerAnimationLoop: false,
dialogType: DialogType.ERROR,
animType: AnimType.BOTTOMSLIDE,
title: 'Error',
desc:
'Make Sure That You Have an Internet Connection Before Pressing Retry',
btnOkOnPress: () =>
Navigator.pushReplacementNamed(context, '/HomePage'),
)..show();
}
}
It looks like user is null in your call to user.updateEmail(email). We can't say why that is from the code you shared, but the quick way to prevent the error is to check for null after calling await _auth.currentUser().
final user = await _auth.currentUser();
if (user != null) {
final result = await InternetAddress.lookup('google.com');
try {
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
user.updateEmail(email);
...
}
} catch (e) {
print(e);
}
}
else {
... do something relevant when no user is signed in
}

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.

How to catch DatabaseError in Flutter Firebase App

I am learning Flutter and I want to catch the exception that should be thrown ( as security rule is correctly rejecting it) at the Flutter Application/device.
Below is the code
try {
FirebaseDatabase.instance.reference().once().then((DataSnapshot snapshot) {
try {
debugPrint(snapshot.toString());
}
on DatabaseError catch (eIn1) {
debugPrint(' onRoot ' + eIn1.toString());
}
});
}on DatabaseError catch (eOut1) {
debugPrint(' on1 ' + eOut1.toString());
}
try {
FirebaseDatabase.instance.reference().child("todo").once().then((DataSnapshot snapshot) {
try {
debugPrint(snapshot.toString());
}
on DatabaseError catch (eIn2) {
debugPrint(' onNode ' + eIn2.toString());
}
});
}on Exception catch (eOut2) {
debugPrint(' on2 ' + eOut2.toString());
}
But the Exception is never thrown or catch by the Android Studio, In logCat I can see the exception,
com.example.flutterlogindemo E/flutter:
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception:
DatabaseError(-3, Permission denied, )
#0 Query.once (package:firebase_database/src/query.dart:84:41)
#1 _HomePageState.initState (package:flutter_login_demo/pages/home_page.dart:48:65)
but could not find a away to catch it in code and then act on the exception.
You can use the catchError to be able to catch the error:
FirebaseDatabase.instance.reference().child("todo").once().then((DataSnapshot snapshot) {
print(snapshot);
})
.catchError((error) {
print("Something went wrong: ${error.message}");
});
https://api.flutter.dev/flutter/package-async_async/DelegatingFuture/catchError.html
Repeating my answer to Flutter: PlatformException thrown by FireBase won't get caught here:
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.

Resources