I've a Flutter App Project which contains levels of permission, so, my main objective with this is allow an manager delete a user, making him not allowed anymore to login, deleting from FirebaseAuth.
I've a permission called "Deactivated" to prevent the user from logging in, but i really want to remove from FirebaseAuth too.
The only way I've found is using the Firebase Cloud Functions, so I tried to do very similar to FlutterFire Docs
When i execute using PostMan, it works perfectly, the user test is deleted as expected:
METHOD: Post
Url: https://us-central1-<DATABASE_NAME>.cloudfunctions.net/deleteUserByEmail/
Body -> Raw:
{
"userEmail": "test#gmail.com"
}
My index.js
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();
exports.deleteUserByEmail = functions.https.onRequest(async (request, response) => {
try {
const userEmail = request.body.userEmail;
admin.auth().getUserByEmail(userEmail)
.then(userRecord => {
const uid = userRecord.uid
return admin.auth().deleteUser(uid)
.then(() => {
console.log("Successfully deleted user");
response.status(200).send('Delete User');
return
})
}).catch(error => {
throw new functions.https.HttpsError('invalid-argument', error.HttpsError);
});
} catch (err) {
throw new functions.https.HttpsError('invalid-argument', "Error passing arguments into");
}
})
Part of my code that calls the code Flutter code:
HttpsCallable callable =
FirebaseFunctions.instance.httpsCallable('deleteUserByEmail');
try {
final resp = await callable.call(<String, dynamic>{
"userEmail" : userModel.email,
});
} on FirebaseFunctionsException catch (e) {
debugPrint(e.toString());
}
Once i tap the button, i receive this error code:
E/flutter (20323): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [firebase_functions/internal] INTERNAL
E/flutter (20323):
E/flutter (20323): #0 StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:653
E/flutter (20323): #1 MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:296
E/flutter (20323): <asynchronous suspension>
E/flutter (20323): #2 MethodChannelHttpsCallable.call
package:cloud_functions_platform_interface/…/method_channel/method_channel_https_callable.dart:23
E/flutter (20323): <asynchronous suspension>
E/flutter (20323): #3 HttpsCallable.call
package:cloud_functions/src/https_callable.dart:49
E/flutter (20323): <asynchronous suspension>
E/flutter (20323):
E/flutter (20323): #0 StandardMethodCodec.decodeEnvelope
package:flutter/…/services/message_codecs.dart:653
E/flutter (20323): #1 MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:296
E/flutter (20323): <asynchronous suspension>
E/flutter (20323): #2 MethodChannelHttpsCallable.call
package:cloud_functions_platform_interface/…/method_channel/method_channel_https_callable.dart:23
After some research I've found that some people had that problem when their code wasn't inside a tryCatch block, but mine was since ever...
I've tried to start admin.initializeApp() parsing the credentials and databaseURL even though my FlutterFire CLI is configured, but didn't work too.
Related
When i sign in with 2FA (email provider, phone provider) i just do signInWithEmailAndPassword, then i catch FirebaseAuthMultiFactorException, get MultiFactorResolver to resolve second factor and sign in successfully. Similar for sign up.
The problem arises when i try to modify user data, like to change password.
I tried the same flow as we do for sign in/ sign up flow, but it doesn't work, it returns FirebaseException instead of FirebaseAuthMultifactorException:
Future<void> changePassword({required String email, required String password, required String newPassword}) async{
final user = _firebaseAuth.currentUser!;
try{
final cred = EmailAuthProvider.credential(email: email, password: password);
await user.reauthenticateWithCredential(cred);
} on FirebaseAuthMultiFactorException catch(e){
log("i need to get resolver here but this line is never executed");
} on FirebaseException catch(e){
log("firebase exception, which doesn`t provide resolver");
rethrow;
}
}
The output is following:
[log] firebase exception, which doesn`t provide resolver
E/flutter (18929): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [firebase_auth/second-factor-required] Please complete a second factor challenge to finish signing into this account.
E/flutter (18929): #0 parseMultiFactorError (package:firebase_auth_platform_interface/src/method_channel/utils/exception.dart:106:5)
E/flutter (18929): #1 platformExceptionToFirebaseAuthException (package:firebase_auth_platform_interface/src/method_channel/utils/exception.dart:49:14)
E/flutter (18929): #2 convertPlatformException (package:firebase_auth_platform_interface/src/method_channel/utils/exception.dart:23:5)
E/flutter (18929): #3 MethodChannelUser.reauthenticateWithCredential (package:firebase_auth_platform_interface/src/method_channel/method_channel_user.dart:181:7)
E/flutter (18929): <asynchronous suspension>
E/flutter (18929): #4 User.reauthenticateWithCredential (package:firebase_auth/src/user.dart:452:7)
E/flutter (18929): <asynchronous suspension>
E/flutter (18929): #5 AuthRepository.changePassword (package:vendor/repositories/auth/auth_repository.dart:43:7)
E/flutter (18929): <asynchronous suspension>
E/flutter (18929): #6 new AuthBloc.<anonymous closure> (package:vendor/blocs/auth_bloc/auth_bloc.dart:50:7)
E/flutter (18929): <asynchronous suspension>
E/flutter (18929): #7 Bloc.on.<anonymous closure>.handleEvent (package:bloc/src/bloc.dart:226:13)
E/flutter (18929): <asynchronous suspension>
That was flutter firebase-sdk issue that was fixed since firebase_auth 4.1.0.
Changelog:
FIX: properly propagate the FirebaseAuthMultiFactorException for all reauthenticate and link methods (#9700). (9ad97c82)
I make small app that app get data from api internet. its work but some time app lose connection with internet and I get this message error:
E/flutter ( 3931): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Connection reset by peer
E/flutter ( 3931): #0 IOClient.send (package:http/src/io_client.dart:88:7)
E/flutter ( 3931): <asynchronous suspension>
E/flutter ( 3931): #1 BaseClient._sendUnstreamed (package:http/src/base_client.dart:93:32)
E/flutter ( 3931): <asynchronous suspension>
E/flutter ( 3931): #2 _withClient (package:http/http.dart:164:12)
E/flutter ( 3931): <asynchronous suspension>
I'm use http library latest version.
SDK flutter 3.3.0 version.
Future fetchMain() async {
var response = await http.get(Uri.parse('https://************.php'));
if (response.statusCode == 200) {
final Data = json.decode(response.body).cast<Map<String, dynamic>>();
List<MainModel> ListData = Data.map<MainModel>(
(json) {
return MainModel.fromJson(json);
}).toList();
return ListData;
} else {
}
}
The connection remains disconnected from the Internet for about 3 minutes and then works again.
Anyone have idea about that problem and how I can solve it?
thank you.
Put a try-catch block in the fetchMain function and handle possible errors
I have this code below which plays a sound every time I hit a button.
AudioPlayer player = AudioPlayer();
Future<void> playSound({required String soundStr}) async {
player.setAsset(soundStr);
player.play();
}
But whenever I hit the button fast, sometimes it will show this error. How can I eliminate this error? I tried adding player.stop(); but it still the same.
E/flutter ( 4312): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(abort, Loading interrupted, null, null)
E/flutter ( 4312): #0 AudioPlayer._setPlatformActive.checkInterruption (package:just_audio/just_audio.dart:1236:7)
E/flutter ( 4312): #1 AudioPlayer._setPlatformActive.setPlatform (package:just_audio/just_audio.dart:1347:11)
E/flutter ( 4312): <asynchronous suspension>
E/flutter ( 4312):
E/flutter ( 4312): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(abort, Loading interrupted, null, null)
E/flutter ( 4312):
Edit: I tried adding await.
Future<void> playSound({required String soundStr}) async {
await player.setAsset(soundStr);
await player.play();
}
If I hit the buttons fast, it will still have error. Though it is now different.
E/flutter (21654): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Connection aborted
E/flutter (21654): #0 AudioPlayer._load (package:just_audio/just_audio.dart:843:11)
E/flutter (21654): <asynchronous suspension>
E/flutter (21654): #1 AudioPlayer.load (package:just_audio/just_audio.dart:770:14)
E/flutter (21654): <asynchronous suspension>
E/flutter (21654): #2 AudioPlayer.setAudioSource (package:just_audio/just_audio.dart:745:18)
E/flutter (21654): <asynchronous suspension>
E/flutter (21654): #3 playSound (package:super_pinoy_quiz/common/generic_methods.dart:396:3)
E/flutter (21654): <asynchronous suspension>
E/flutter (21654):
I'm using this package: just_audio: ^0.9.29
Though I tried using different package but it also encounters the same error when hitting the button fast: audioplayers: ^1.1.1
Both setAsset and play are future method, you can await for setting assets
Future<void> playSound({required String soundStr}) async {
await player.setAsset(soundStr);
await player.play();
}
I'm using Dio in my app and I want it to save cookies. It turns out I have to download three additional packages to do that: cookie_jar, dio_cookie_manager and path_provider.
I need to:
get application document directory:
Directory docDir = await getApplicationDocumentsDirectory();
pass it to PersistCookieJar
PersistCookieJar(storage: FileStorage(appDocDir.path + '/.cookies/'));
and add it to interceptors:
dio.interceptors.add(CookieManager(_cookieJar));
My problem is with the first part. For some reason, getApplicationDocumentsDirectory(); throws an error when not used inside a StatefulWidget widget.
I have two questions:
Why on earth would getting a path require a StatefulWidget?
How can I do what I want? I need to initialize Dio as early as possible so that by the time the UI loads, the user is already (or almost) logged in. Plus, I don't want to put the logic of initiating the client object inside the UI code, that might for example cause it to be initiated multiple times whenever the widget is created.
What my code looks like right now:
Future<void> initStuff() async {
initLocator();
Directory docDir = await getApplicationDocumentsDirectory(); // throws
print('docDir = ${docDir.path}');
Client cli = Client(docDir);
locator.registerSingleton<Client>(cli);
// ...
}
void main() async {
await initStuff();
runApp(MyApp());
}
Client constructor:
Client(Directory appDocDir) {
final _cookieJar = PersistCookieJar(storage: FileStorage(appDocDir.path + '/.cookies/'));
dio = Dio()
..options.baseUrl = Utils.SERVER_ADDRESS
..options.sendTimeout = 5000
..options.receiveTimeout = 5000
..options.connectTimeout = 5000
..interceptors.add(CookieManager(_cookieJar));
}
The error I'm getting:
E/flutter (24953): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Null check operator used on a null value
E/flutter (24953): #0 MethodChannel.binaryMessenger
package:flutter/…/services/platform_channel.dart:142
E/flutter (24953): #1 MethodChannel._invokeMethod
package:flutter/…/services/platform_channel.dart:148
E/flutter (24953): #2 MethodChannel.invokeMethod
package:flutter/…/services/platform_channel.dart:331
E/flutter (24953): #3 MethodChannelPathProvider.getApplicationDocumentsPath
package:path_provider_platform_interface/src/method_channel_path_provider.dart:50
E/flutter (24953): #4 getApplicationDocumentsDirectory
package:path_provider/path_provider.dart:138
E/flutter (24953): #5 initStuff
package:proj/main.dart:20
E/flutter (24953): #6 main
package:proj/main.dart:63
E/flutter (24953): #7 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:142:25)
E/flutter (24953): #8 _rootRun (dart:async/zone.dart:1354:13)
E/flutter (24953): #9 _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter (24953): #10 _runZoned (dart:async/zone.dart:1789:10)
E/flutter (24953): #11 runZonedGuarded (dart:async/zone.dart:1777:12)
E/flutter (24953): #12 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:138:5)
E/flutter (24953): #13 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
E/flutter (24953): #14 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
OK: Thank you for updating your post.
The error is: Unhandled Exception: Null check operator used on a null value
It's coming from the 3rd party library call getApplicationDocumentsDirectory(), and it's occurring because you're calling a (currently uninitialized) value with null-safety enabled (a Good Thing!).
SUGGESTIONS:
Using a StatefulWidget is a bit more work - but it makes sense here. It also happens to resolve the problem for you, correct?
You might try making docDir nullable (e.g. String? path). This is exactly what the getApplicationDocument page shows:
https://pub.dev/documentation/path_provider/latest/path_provider/getApplicationDocumentsDirectory.html
Future<Directory> getApplicationDocumentsDirectory() async {
final String? path = await _platform.getApplicationDocumentsPath();
if (path == null) {
throw MissingPlatformDirectoryException(
'Unable to get application documents directory');
}
return Directory(path);
}
Finally, check out these links:
https://stackoverflow.com/a/67990442/421195
https://stackoverflow.com/a/68876902/421195
Run this in main() before everything else:
WidgetsFlutterBinding.ensureInitialized();
Here is my code, I want to store data to Firebase Database when user enter button but getting the following error
onTap: () {
if(_controllershopname.text==''||_controllerstreet.text==''||_controllershopnumber.text==''||_controllercity.text==''||_controllerstate.text=='')
{
Fluttertoast.showToast(msg: "Please Fill all the fields");
}else{
DatabaseReference databseRefrence = FirebaseDatabase.instance.reference().child("ShopKeeper");
databseRefrence.child(widget.number).push().set(
{
'Name':widget.userName,
'ShopName': _controllershopname.text,
'ShopNumber':_controllershopnumber.text,
'ShopStreet':_controllerstreet.text,
'ShopCity':_controllercity.text,
'ShopState':_controllerstate.text,
'OnlineDelivery':"Yes",
});
Here is the error
E/flutter (26078): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Invalid argument: Instance of 'TextEditingController'
E/flutter (26078): #0 StandardMessageCodec.writeValue (package:flutter/src/services/message_codecs.dart:392:7)
E/flutter (26078): #1 StandardMessageCodec.writeValue. (package:flutter/src/services/message_codecs.dart:389:9)
E/flutter (26078): #2 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter (26078): #3 StandardMessageCodec.writeValue (package:flutter/src/services/message_codecs.dart:387:13)
E/flutter (26078): #4 StandardMessageCodec.writeValue. (package:flutter/src/services/message_codecs.dart:389:9)
E/flutter (26078): #5 _LinkedHashMapMixin.forEach (dart:collection-
Did you create instances of your "TextEdittingControllers"? If you did, then you should try trimming your text before saving to the database:
onTap: () {
if(_controllershopname.text==''||_controllerstreet.text==''||_controllershopnumber.text==''||_controllercity.text==''||_controllerstate.text=='')
{
{
Fluttertoast.showToast(msg: "Please Fill all the fields");
}else{
DatabaseReference databseRefrence = FirebaseDatabase.instance.reference().child("ShopKeeper");
databseRefrence.child(widget.number).push().set(
{
'Name':widget.userName,
'ShopName': _controllershopname.text.trim(),
'ShopNumber':_controllershopnumber.text.trim(),
'ShopStreet':_controllerstreet.text.trim(),
'ShopCity':_controllercity.text.trim(),
'ShopState':_controllerstate.text.trim(),
'OnlineDelivery':"Yes",
});