未来未从预期的等待功能返回

时间:2019-06-01 21:22:07

标签: flutter dart

函数signInWithGoogle调用getUser函数从Firestore数据库中检索用户信息,并期望以User作为返回值。因为这是一个Firestore API调用,所以getUser返回的User是Future,并且等待等待getUser调用。

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

但是,在signInWithGoogle函数中,未从Future接收到User,如在执行debugPrint(“ user schedule 0:” + u.schedule [0] .toJson())时对schedule的空引用中所示。

我尝试过多种设置返回值的方法(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)

当在getUser函数中使用相同的打印时间表[0]调用时,我希望从signInWithGoogle打印时间表[0]时不会收到空引用错误。

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

如果您需要其他任何信息,请告诉我。

2 个答案:

答案 0 :(得分:1)

问题就在这里

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)时,您会从something中得到返回值,在这种情况下为null,而不是someFuture的解析值。 / p>

这是我们recommend not to mix async/await with .then

的原因之一

答案 1 :(得分:0)

我不知道这是否是导致问题的原因,但是您正在混合期货和异步/唤醒。您真的只需要一个。这行:

 User user = await getUser(firebaseUser.uid).then((u) {debugPrint("user schedule 0: " + u.schedule[0].toJson());});

...可能看起来更简单一些:

User user = await getUser(firebaseUser.uid);

print(user.schedule[0].toJson());

异步/等待 返回未来。不需要将.then()回调与async / await语句一起放置。

相关问题