函数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个小时的代码后,我无法弄清楚正在发生什么。
如果您需要其他任何信息,请告诉我。
答案 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>
答案 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语句一起放置。