未捕获 Firebase Auth 错误 + 奇怪的错误

Firebase Auth errors not being caught + weird errors

我正在做一个需要 Firebase Auth 的项目。

当我尝试在已使用的电子邮件中捕获错误时,我在控制台中收到错误,但 catch 语句从未执行。我也(总是)得到一个奇怪的空值错误,但这似乎并没有破坏任何东西。 第二条错误消息是我关注的重点。 以下是错误消息:

Error: Unexpected null value.
    at Object.throw_ [as throw] (http://localhost:33663/dart_sdk.js:5067:11)
    at Object.nullCheck (http://localhost:33663/dart_sdk.js:5394:30)
    at http://localhost:33663/packages/fischerliste/message_list.dart.lib.js:983:62
    at _RootZone.runUnary (http://localhost:33663/dart_sdk.js:40441:59)
    at _FutureListener.then.handleValue (http://localhost:33663/dart_sdk.js:35363:29)
    at handleValueCallback (http://localhost:33663/dart_sdk.js:35931:49)
    at Function._propagateToListeners (http://localhost:33663/dart_sdk.js:35969:17)
    at _Future.new.[_completeWithValue] (http://localhost:33663/dart_sdk.js:35817:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:33663/dart_sdk.js:35838:35)
    at Object._microtaskLoop (http://localhost:33663/dart_sdk.js:40708:13)
    at _startMicrotaskLoop (http://localhost:33663/dart_sdk.js:40714:13)
    at http://localhost:33663/dart_sdk.js:36191:9
Error: [firebase_auth/email-already-in-use] The email address is already in use by another account.
    at Object.throw_ [as throw] (http://localhost:33663/dart_sdk.js:5067:11)
    at firebase_auth_web.FirebaseAuthWeb.new.createUserWithEmailAndPassword (http://localhost:33663/packages/firebase_auth_web/firebase_auth_web.dart.lib.js:156:23)
    at createUserWithEmailAndPassword.throw (<anonymous>)
    at http://localhost:33663/dart_sdk.js:40576:38
    at _RootZone.runBinary (http://localhost:33663/dart_sdk.js:40445:59)
    at _FutureListener.thenAwait.handleError (http://localhost:33663/dart_sdk.js:35374:33)
    at handleError (http://localhost:33663/dart_sdk.js:35947:51)
    at Function._propagateToListeners (http://localhost:33663/dart_sdk.js:35973:17)
    at _Future.new.[_completeError] (http://localhost:33663/dart_sdk.js:35823:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:33663/dart_sdk.js:35859:31)
    at Object._microtaskLoop (http://localhost:33663/dart_sdk.js:40708:13)
    at _startMicrotaskLoop (http://localhost:33663/dart_sdk.js:40714:13)
    at http://localhost:33663/dart_sdk.js:36191:9

这是我的代码:

(您可以在 https://github.com/fischerliste/fischerliste/tree/master/lib 找到所有内容)

import 'package:flutter/scheduler.dart';
import 'data/message_dao.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';

class MessageListState extends State<MessageList> {
  MessageListState();
  FirebaseApp app = Firebase.app();
  String? uid;
  SharedPreferences? prefs;
  FirebaseAuth auth = FirebaseAuth.instanceFor(app: Firebase.app());
  UserCredential? credential;

  @override
  void initState() {
    SharedPreferences.getInstance().then((SharedPreferences? value) {
      prefs = value;
      uid = prefs!.getString('UID');
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    if (uid == null) {
      SchedulerBinding.instance?.addPostFrameCallback((_) {
        Navigator.of(context)
            .push(showSigninPopup(context, auth))
            .then((value) {
          credential = value;
          prefs!.setString('UID', uid!);
          return uid = "1234test";
        });
      });
    }

    return Scaffold();
//layout code here removed to make it shorter, but in case you want to
//see it, github link can be found above.
  }
}

DialogRoute showSigninPopup(BuildContext buildcontext, FirebaseAuth auth) {
  UserCredential? credential;
  TextEditingController emailController = TextEditingController();
  TextEditingController passwordController = TextEditingController();

  bool createUser() {
    try {
      auth.createUserWithEmailAndPassword(
              email: emailController.text, password: passwordController.text)
          .then((UserCredential? value) {
        credential = value;
      });
    } catch (e) {
      print('==================');
      print('This never gets executed');
      print(e);
    }
    return true;
  }

  bool checkSignin() {
    try {
      auth.signInWithEmailAndPassword(
              email: emailController.text, password: passwordController.text)
          .then((value) {
        print(value);
      });
    } catch (exception) {
      print(exception);
    }
    return true;
  }

  return DialogRoute(
    barrierDismissible: false,
    builder: (context) {
      return AlertDialog(
        title: const Text("Bitte anmelden!"),
        content: Column(
          children: [
            TextField(
              controller: emailController,
              decoration: const InputDecoration(labelText: 'Email'),
            ),
            TextField(
              controller: passwordController,
              decoration: const InputDecoration(labelText: 'Passwort'),
              obscureText: true,
            ),
          ],
          mainAxisSize: MainAxisSize.min,
        ),
        actions: <Widget>[
          TextButton(
              onPressed: () {
                createUser();
                Navigator.pop(context);
              },
              child: const Text("Registrieren")),
          TextButton(
              onPressed: () {
                if (checkSignin()) {
                  Navigator.pop(context);
                }
              },
              child: const Text("Anmelden")),
        ],
      );
    },
    context: buildcontext,
  );
}

class MessageList extends StatefulWidget {
  MessageList({Key? key}) : super(key: key);
  final messageDao = MessageDao();

  @override
  MessageListState createState() => MessageListState();
}

createUserWithEmailAndPassword returns a Future 的调用,可能成功也可能失败。但是 Future 的失败只会在您 await 调用时转化为异常。

所以:

try {
    credential = await auth.createUserWithEmailAndPassword(
          email: emailController.text, password: passwordController.text);
} catch (e) {
  print('==================');
  print('This never gets executed');
  print(e);
}

如果您想了解更多相关信息,我建议您观看此视频:Firebase Authentication in Flutter (The Boring Flutter Development Show, Ep. 55) - YouTube