Boatti
Boatti

Reputation: 229

How can I get a specific field into Firestore in Flutter

I have this function which is called when I push an Upload Button. It should create a collection in Firestore called userPosts with postId, ownerId, and mediaUrl. Everything is working except username because I have to take it from another collection in Firestore called users. So I have this error: Unhandled Exception: Invalid argument: Instance of 'Future <String>' How can I fix this? Thanks!

final userRef = FirebaseFirestore.instance.collection('users');
final postsRef = FirebaseFirestore.instance.collection('posts');

createPostInFirestore({required String mediaUrl}) {
    postsRef.doc(user!.uid).collection("userPosts").doc(postId).set({
      "postId": postId,
      "ownerId": user!.uid,
      "username": userRef.doc(user!.uid).get().then((snapshot) {
        return snapshot.data()!['username'].toString();
      }),
      "mediaUrl": mediaUrl,
      "timestamp": timestamp,
      "likes": {},
    });
  }

Upvotes: 0

Views: 54

Answers (1)

Gwhyyy
Gwhyyy

Reputation: 9206

the get() and set() methods are asynchronous ( needs time to resolve ), so we need to make the function asynchronous with the async keyword, then wait to get the username, after that, wait to update the data with set(). try this:

   final userRef = FirebaseFirestore.instance.collection('users');
  final postsRef = FirebaseFirestore.instance.collection('posts');

  Future<void> createPostInFirestore({required String mediaUrl}) async {
    final username = await userRef.doc(user!.uid).get().then((snapshot) {
        return (snapshot.data() as Map<String, dynamic>)!['username'].toString();
      });
    await postsRef.doc(user!.uid).collection("userPosts").doc(postId).set({
      "postId": postId,
      "ownerId": user!.uid,
      "username": username,
      "mediaUrl": mediaUrl,
      "timestamp": timestamp,
      "likes": {},
    });
  }

then on the onPressed or the method which will execute this function, you need to wait for it also like this:

onPressed: () async {
await createPostInFirestore("your string URL here");
}

now it will work fine

Upvotes: 1

Related Questions