首页 > 解决方案 > 未按预期从等待函数返回未来

问题描述

该函数signInWithGoogle调用该getUser函数以从 Firestore 数据库中检索用户信息,并期望 aUser作为返回值。因为这是一个 Firestore API 调用,所以User返回的getUser是 aFuturegetUser使用await.

getUser函数中,User按预期填充并使用debugPrint("new user schedule 0: " + i[0].toJson());

然而,在signInWithGoogle函数中,User没有从 接收返回Future<User>,如schedule执行时的空引用所示debugPrint("user schedule 0: " + u.schedule[0].toJson());

我尝试以多种方式(getUser函数)设置返回值,包括在设置它的值并返回它之前分别实例化一个用户类。

Future<User> getUser(_uid) async {
    DocumentSnapshot qs = await Firestore.instance
        .collection('users')
        .document(_uid)
        .get();
    if (qs.exists) {
      setState(() {
        state.loadingStatus = "Getting User Information";
      });
      return new User(
        schedule: await getRecipes(
            Firestore.instance
                .collection('users')
                .document(_uid)
                .collection('schedule')
        ).then((i) {
          debugPrint("get schedule");
          debugPrint("new user schedule 0: " + i[0].toJson());
        }).catchError((error) {
          debugPrint('Error: $error');
        }),
        favorites: await getRecipes(
            Firestore.instance
                .collection('users')
                .document(_uid)
                .collection('favorites')
        ).then((i) {debugPrint("get favorites");}).catchError((error) {
          debugPrint('Error: $error');
        }),
        subscription: await getSubscription(_uid).then((i) {debugPrint("get subscription");}),
        pantry: await getIngredientsList(
            Firestore.instance
                .collection('users')
                .document(_uid)
                .collection('pantry')
        ).then((i) {debugPrint("get pantry");}).catchError((error) {
          debugPrint('Error: $error');
        }),
        shopping: await getIngredientsList(
            Firestore.instance
                .collection('users')
                .document(_uid)
                .collection('shopping')
        ).then((i) {debugPrint("get shopping list");}).catchError((error) {
          debugPrint('Error: $error');
        }),
        preferences: await getPreferences(_uid).then((i) {debugPrint("get preferences");}),
      );
    }else {
      setState(() {
        state.loadingStatus = "Creating new User Information";
      });
      return User.newUser();
    }
  }

  Future<Null> signInWithGoogle() async {
    setState(() {
      state.loadingStatus = "Signing in with Google";
    });
    if (googleAccount == null) {
      // Start the sign-in process:
      googleAccount = await googleSignIn.signIn();
    }
    FirebaseUser firebaseUser = await signIntoFirebase(googleAccount);
    User user = await getUser(firebaseUser.uid);
    debugPrint("user schedule 0: " + user.schedule[0].toJson());
    setState(() {
      state.isLoading = false;
      state.loadingStatus = "";
      state.user = firebaseUser;
      state.userInfo = user;
    });
  }
I/flutter (17962): new user schedule 0: {Proper data is printed here...
I/flutter (17962): get favorites
I/flutter (17962): get subscription
I/flutter (17962): get pantry
I/flutter (17962): get shopping list
I/flutter (17962): get preferences
E/flutter (17962): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
E/flutter (17962): Receiver: null
E/flutter (17962): Tried calling: [](0)

当函数中对 print 的相同调用起作用 时,我希望在打印schedule[0]from时不会收到空引用错误。signInWithGoogleschedule[0]getUser

这可能是我想念的一些愚蠢的简单事情,但是在查看过去 3 小时的代码后,我无法弄清楚发生了什么。

如果您需要任何进一步的信息,请告诉我。

标签: flutterdart

解决方案


问题就在这里:

schedule: await getRecipes(
  Firestore.instance
      .collection('users')
      .document(_uid)
      .collection('schedule')
  ).then((i) {
    debugPrint("get schedule");
    debugPrint("new user schedule 0: " + i[0].toJson());

    // this is a problem, there is no return!

  }).catchError((error) {
    debugPrint('Error: $error');
  }),

这传递了一个null论点schedule:,这不是你的意图。当您await someFuture.then(something)从 中获取返回值somethingnull在这种情况下,不是someFuture.

这是我们建议不要混用async/await的原因之一.then


推荐阅读