On each user auth and user creation, I have an error message where the method is called on null.
The user is created when I sign up but it prevents me to continue the use without having to restart the apps.
I placed all the call related to user creation in firebase, I can not find the root cause of the null.
class AuthNotifier with ChangeNotifier {
FirebaseUser _user;
FirebaseUser get user => _user;
void setUser(FirebaseUser user) {
_user = user;
_createUserDocument();
if (user != null) {
_createUserDocument();
}
notifyListeners();
}
void _createUserDocument() async {
CollectionReference users = Firestore.instance.collection('Users');
DocumentSnapshot user_document = await users.document(_user.uid).get();
if (!user_document.exists) {
// Create a document for the user if he doesn't have one
users.document(_user.uid).setData({
'favorites': []
}
);
}
}
Future<void> toggleFavorite(String foodId) async {
CollectionReference users = Firestore.instance.collection('Users');
DocumentSnapshot user_document = await users.document(_user.uid).get();
// If using collectionGroup, we can directly filter the foodId without looping through it.
// Fetch and see if it is already in the list // TODO: Use class-wide, static, event-updated instance
for (dynamic reference in user_document.data['favorites']) {
if (reference.documentID == foodId) {
// Remove it from the list and exit so it doesn't get added later in the function
users.document(_user.uid).updateData({'favorites': FieldValue.arrayRemove([reference])}).catchError((error) => print("Failed to remove favorite element: ${error}"));
notifyListeners();
return;
}
}
// Get the matching food DocumentReference object
var food = await Firestore.instance.collection('Foods').document(foodId).get();
// Add to the favorite list if it wasn't
users.document(_user.uid).updateData({'favorites': FieldValue.arrayUnion([food.reference])}).catchError((error) => print("Failed to add new favorite element : ${error}"));
notifyListeners();
}
Future<bool> isFavorite(String foodId) async {
List<dynamic> favorites = await _getFavorites();
for (DocumentReference favorite in favorites) {
if (favorite.documentID == foodId) {
return true;
}
}
return false;
}
Future<List<dynamic>> getFavorites() async {
List<dynamic> favorites = await _getFavorites();
List<String> favorites_documentid = [];
favorites.forEach((reference) { favorites_documentid.add(reference.documentID); });
return favorites_documentid;
}
Future<List<dynamic>> _getFavorites() async { // TODO: Use class-wide list that updates only when a a favorite is added or removed. Even listen to a snapshot for this, if there are lots of favorites.
DocumentSnapshot snapshot = await Firestore.instance
.collection('Users').document(_user.uid).get();
return snapshot.data['favorites']; // DocumentReference
}
}
You need to
await
for async operations to complete.And
await
forsetUser()
as well.Update. Use
snapshot.data()
instead ofsnaphot.data
: