0

Im reading the firestore flutter sdk documentation. It shows how to use a serializable class to automatically convert documents to objects with this example:

class Movie {
  Movie({required this.title, required this.genre});

  Movie.fromJson(Map<String, Object?> json)
    : this(
        title: json['title']! as String,
        genre: json['genre']! as String,
      );

  final String title;
  final String genre;

  Map<String, Object?> toJson() {
    return {
      'title': title,
      'genre': genre,
    };
  }
}

and then create a new document using the add function:

 await moviesRef.add(
    Movie(
      title: 'Star Wars: A New Hope (Episode IV)',
      genre: 'Sci-fi'
    ),
  );

How would I get the documentId after adding a new document or when querying?

2 Answers2

1

I tried to achieve a behavior like this before, in Firebase Firestore, either you call moviesRef.add() then firebase will add a new document with a completely auto-generated uid, or if you're having a specific uid then you can just use the moviesRef.doc(hereTheId).set().

However , the moviesRef.add() returns a DocumentReference which you can get from it the is like this example:

using then:

collection('students').add(/*...*/)

.then((val)=> print(val.documentID)});

using await/async:

final newDocument = await moviesRef.add(/*...*/);
print(newDocument.documentID);

You can also get a completely auto-generated uid before sending the request , then call moviesRef.doc(hereTheId).set() like this:

    final String id  = moviesRef.doc().id;
    moviesRef.doc(id).set(/*...*/)`

Hope this helps.

Gwhyyy
  • 7,554
  • 3
  • 8
  • 35
  • I want to use withConverter, so the add would return a movie object, instead of documentReference and I cant find a way to add id to the movie class – PortalGamesMais Nov 20 '22 at 08:42
  • then did you tried the secondway I added – Gwhyyy Nov 20 '22 at 09:04
  • The second way wouldnt solve the following scenario: I query a collection, the user chooses a document and I need to save the id of this document in another document, as a reference. There is no obvious way to access documentid when using withConverter. I mean I found a few workarounds, I could add a second id as a key value pair or create a custom function to convert the raw data to an object so I could have id in it. It just feels that having an Id property in the model is a pretty important feature, I don’t understand why they would make it so complicated. – PortalGamesMais Nov 20 '22 at 16:45
1

I think we also need to manipulate the Ref to be able to use like you mentioned above with add method, which will get the Future<DocumentReference> add(Movie data) Returns a DocumentReference with an auto-generated ID, after populating it with provided data.

As shown in here like following:

final moviesRef = FirebaseFirestore.instance.collection('movies').withConverter<Movie>(
      fromFirestore: (snapshot, _) => Movie.fromJson(snapshot.data()!),
      toFirestore: (movie, _) => movie.toJson(),
    );

And while adding it you need added document id you can achieve it like this :

final moviesRef =
      FirebaseFirestore.instance.collection('movies').withConverter<Movie>(
            fromFirestore: (snapshot, _) => Movie.fromJson(snapshot.data()!),
            toFirestore: (movie, _) => movie.toJson(),
          );

  // Add a movie
  DocumentReference docreference = await moviesRef.add(
    Movie(title: 'Star Wars: A New Hope (Episode IV)', genre: 'Sci-fi'),
  );

  String id = docreference.id;

  debugPrint('documentId: $id'); // will give you the added Document documentId.

Rohit Kharche
  • 2,541
  • 1
  • 2
  • 13
  • I found a solution using this method: using a late variable in the model class and then adding id manually layer, I just prefer to avoid using late because it’s not 100% safe code. But I just realized I wasn’t reading carefully, I hadn’t realized until now that snapshot.data was being manually passed as a parameter, if I instead pass snapshot itself I could probably get documentId from it, I will try it later. – PortalGamesMais Nov 25 '22 at 12:20