【问题标题】:How to catch DatabaseError in Flutter Firebase App如何在 Flutter Firebase 应用程序中捕获 DatabaseError
【发布时间】:2020-05-15 15:20:33
【问题描述】:

我正在学习 Flutter,我想在 Flutter 应用程序/设备上捕获应该抛出的异常(因为安全规则正确拒绝它)。

下面是代码

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

但异常不会被 Android Studio 抛出或捕获,在 logCat 中我可以看到异常,

com.example.flutterlogindemo E/flutter: [错误:flutter/lib/ui/ui_dart_state.cc(157)] 未处理的异常: 数据库错误(-3,权限被拒绝,) #0 Query.once(包:firebase_database/src/query.dart:84:41) #1 _HomePageState.initState (package:flutter_login_demo/pages/home_page.dart:48:65)

但找不到在代码中捕获它然后处理异常的方法。

【问题讨论】:

    标签: firebase flutter exception dart firebase-realtime-database


    【解决方案1】:

    在这里重复我对Flutter: PlatformException thrown by FireBase won't get caught 的回答:

    如果 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

    【讨论】:

      【解决方案2】:

      您可以使用catchError 来捕获错误:

      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

      【讨论】:

        猜你喜欢
        • 2021-04-25
        • 2018-06-03
        • 2021-09-08
        • 2020-08-26
        • 2018-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-04
        相关资源
        最近更新 更多