Flutter:FireBase 抛出的 PlatformException 不会被捕获

Posted

技术标签:

【中文标题】Flutter:FireBase 抛出的 PlatformException 不会被捕获【英文标题】:Flutter: PlatformException thrown by FireBase won't get caught 【发布时间】:2020-07-04 00:43:52 【问题描述】:

我有一个用于使用 firebase_auth 登录 Firebase 的函数,但是,无论何时抛出异常,它都不会被捕获并且仍然出现在 android Studio 控制台中,也不会运行 catch 块中的打印语句.

我该如何解决这个问题?

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

【问题讨论】:

【参考方案1】:

signInWithEmailAndPassword 返回一个Future<AuthResult>(它是异步的),因此在调用异步方法时需要使用catchError 方法来捕捉错误:

 FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password).then((result) 
    print(result);
)
.catchError((error) 
    print("Something went wrong: $error.message");
  );

检查以下内容:

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

【讨论】:

那么处理异常的常规 try/catch 方法不适用于异步函数吗? 不,那样你将无法捕捉到期望 唯一的方法是使用catcherror请检查链接 Here 和其他 *** 链接上,try/catch 成功捕获异常。【参考方案2】:

如果 Firebase 调用在 async 函数内并且在调用 Firebase 时使用了 await 语句,则 try catch 块将起作用。

例如,在以下代码中,获取令牌的错误将被 on PlatformException catch (... 块捕获,但将令牌写入 FB RTDB 不会出现错误:

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

而添加await 语句(如下面的代码)也会捕获写入FB RTDB 的错误:

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

如果您不想或不能使用await,那么根据彼得的回答,解决方案是使用catchError 语句而不是try catch

【讨论】:

以上是关于Flutter:FireBase 抛出的 PlatformException 不会被捕获的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 中捕获云 Firestore 文档快照错误

无法使用 Flutter Mobile 上传到 Firebase 存储

Flutter:Xcode 中的 firebase_admob 构建失败

无法从 firebase 查询 Flutter 中获取单个记录

Flutter Web:文件选择器抛出“无效参数(路径):不能为空”错误

使用 Flutter 永久存储数据