Raj Chaudhary
Raj Chaudhary

Reputation: 1772

Firestore: get document back after adding it / updating it without additional network calls

Is it possible to get document back after adding it / updating it without additional network calls with Firestore, similar to MongoDB?

I find it stupid to first make a call to add / update a document and then make an additional call to get it.

Upvotes: 25

Views: 15037

Answers (5)

Sebastián Zegada
Sebastián Zegada

Reputation: 15

Well I was trying the same, but, I noticed that I already have the data in my code. So, instead of getting the document back, I decided to update my current object. Something like this:

// Get the current document, e.g. some user
const querySnapshot = await firebase
    .firestore()
    .collection('users')
    .doc(docId)
    .get()

// Get the data, e.g. user data
let userData = querySnapshot.doc.data()
// Some business logic
...

if (condition) {
    // update document
    await firebase
        .firestore()
        .collection('users')
        .doc(docId)
        .update({phone: someNumber})
    
    // Update your current data
    userData.phone = someNumber
}

It saves a network call and accomplish what we intended.

Also, if the intention is to create a new document and then using it as a reference, you can store the newly created document's id in one variable:

if (!userData) {
    const newUser = {name: someName, address: someAddress}
    const res = await firebase
        .firestore()
        .collection('users')
        .add({ ...newUser })
    userData = newUser
    userData.id = res.id
}

Hope this helps!

Upvotes: 0

Cristhian Apolo
Cristhian Apolo

Reputation: 11

I did this to get the ID of a new Document created, and then use it in something else.

Future<DocumentReference<Object>> addNewData() async {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  final CollectionReference _userCollection = _firestore.collection('users');

  return await _userCollection 
    .add({ 'data': 'value' })
    .whenComplete(() => {
      // Show good notification
    })
    .catchError((e) {
      // Show Bad notification
    });
}

And here I obtain the ID:

await addNewData()
  .then((document) async {
    // Get ID
    print('ID Document Created ${document.id}');
  });

I hope it helps.

Upvotes: -1

Renaud Tarnec
Renaud Tarnec

Reputation: 83163

As you have probably seen in the documentation of the Node.js (and Javascript) SDKs, this is not possible, neither with the methods of a DocumentReference nor with the one of a CollectionReference.

More precisely, the set() and update() methods of a DocumentReference both return a Promise containing void, while the CollectionReference's add() method returns a Promise containing a DocumentReference.


Side Note (in line with answer from darrinm below): It is interesting to note that with the Firestore REST API, when you create a document, you get back (i.e. through the API endpoint response) a Document object.

Upvotes: 30

darrinm
darrinm

Reputation: 9257

This appears to be an arbitrary limitation of the the Firestore Javascript API. The Firestore REST API returns the updated document on the same call.

https://firebase.google.com/docs/firestore/reference/rest/v1beta1/projects.databases.documents/patch

Upvotes: 3

Frank van Puffelen
Frank van Puffelen

Reputation: 599661

When you add a document to Cloud Firestore, the server can affect the data that is stored. A few ways this may happen:

  • If your data contains a marker for a server-side timestamp, the server will expand that marker into the actual timestamp.
  • Your data data is not permitted according to your server-side security rules, the server will reject the write operation.

Since the server affects the contents of the Document, the client can't simply return the data that it already has as the new document. If you just want to show the data that you sent to the server in your client, you can of course do so by simply reusing the object you passed into setData(...)/addDocument(data: ...).

Upvotes: 1

Related Questions