Jim Jones
Jim Jones

Reputation: 2837

How to update a single firebase firestore document

After authenticating i'm trying to lookup a user document at /users/, then i'd like to update the document with data from auth object as well some custom user properties. But I'm getting an error that the update method doesn't exist. Is there a way to update a single document? All the firestore doc examples assume you have the actual doc id, and they don't have any examples querying with a where clause.

firebase.firestore().collection("users").where("uid", "==", payload.uid)
  .get()
  .then(function(querySnapshot) {
      querySnapshot.forEach(function(doc) {
          console.log(doc.id, " => ", doc.data());
          doc.update({foo: "bar"})
      });
 })

Upvotes: 104

Views: 238543

Answers (8)

Dixit Bhojani
Dixit Bhojani

Reputation: 66

firebase.firestore().collection("users")
   .where("uid", "==", payload.uid)
   .get()
   .then(function(querySnapshot) {
       querySnapshot.forEach(function(doc) {
       console.log(doc.id, " => ", doc.data());

       // Create a reference to the document and update it
       firebase.firestore().collection("users").doc(doc.id).update({
          foo: "bar"
          // Add other properties you want to update here
       })
       .then(() => {
          console.log("Document successfully updated!");
       })
       .catch((error) => {
          console.error("Error updating document: ", error);
       });
   });
})
.catch((error) => {
   console.error("Error getting documents: ", error);
});

You can try like this.

Upvotes: 1

Daniel Danielecki
Daniel Danielecki

Reputation: 10590

To add to these answers: if you don't have access to doc and are looking to get the document dynamically.

Sadly, in React Native environment, I couldn't find a way to import doc, to get the id. I'm working with https://rnfirebase.io/firestore/usage. It can be the same case for some less common environments relying on Firebase plugin/libraries.

In that case console.log(documentSnapshot.ref); will return you what you can find below.

enter image description here

as you could see, while working with the raw response, it can be accessed via documentSnapshot.ref._documentPath._parts[1]. documentSnapshot is of course part of querySnapshot. In the question, it's referred as doc.

Now you can pass it to the call:

import firestore from "@react-native-firebase/firestore"; // you could have it imported from a different library, but always better to just import firestore rather than entire firebase from which you can (also) get firestore.
...
firestore()
  .collection(YOUR_COLLECTION_NAME)
  .doc(documentSnapshot.ref._documentPath._parts[1]) // or assign it to a variable, and then use - better
  .update({...})
  .then(() => {})
  .catch(() => {})
  .finally(() => {});

Upvotes: 0

Juan Lara
Juan Lara

Reputation: 6854

You can precisely do as follows (https://firebase.google.com/docs/reference/js/v8/firebase.firestore.DocumentReference):

// firebase v8
var db = firebase.firestore();

db.collection("users").doc(doc.id).update({foo: "bar"});

//firebase v9
const db = getFirestore();
async (e) => { //...
 await updateDoc(doc(db, "users", doc.id), {
    foo: 'bar'
  });
//....

check out the official documentation as well

Upvotes: 127

Peter Palmer
Peter Palmer

Reputation: 854

-- UPDATE FOR FIREBASE V9 --

In the newer version of Firebase this is done like this:

import { doc, updateDoc } from "firebase/firestore";

const washingtonRef = doc(db, "cities", "DC");

// Set the "capital" field of the city 'DC'
await updateDoc(washingtonRef, {
  capital: true
});

Upvotes: 34

navaneeth001
navaneeth001

Reputation: 99

correct way to do this is as follows; to do any data manipulation in snapshot object we have to reference the .ref attribute

 firebase.firestore().collection("users").where("uid", "==", payload.uid)
  .get()
  .then(function(querySnapshot) {
      querySnapshot.forEach(function(doc) {
          console.log(doc.id, " => ", doc.data());
          doc.ref.update({foo: "bar"})//not doc.update({foo: "bar"})
      });
 })

Upvotes: 3

Raimon
Raimon

Reputation: 21

You only need to found official ID of document, code here!

    enter code here
    //Get user mail (logined)
    val db = FirebaseFirestore.getInstance()
    val user = Firebase.auth.currentUser
    val mail = user?.email.toString()

       //do update
       val update = db.collection("spending").addSnapshotListener { snapshot, e ->
                val doc = snapshot?.documents
                doc?.forEach {
                    //Assign data that I got from document (I neet to declare dataclass) 
                    val spendData= it.toObject(SpendDt::class.java)
                    if (spendData?.mail == mail) {
                        //Get document ID
                        val userId = it.id
                        //Select collection
                        val sfDocRef = db.collection("spendDocument").document(userId)
                        //Do transaction
                        db.runTransaction { transaction ->
                            val despesaConsum = hashMapOf(
                                "medalHalfYear" to true,
                            )
                            //SetOption.merege() is for an existing document
                            transaction.set(sfDocRef, despesaConsum, SetOptions.merge())
                        }
                    }

                }
            }
}
data class SpendDt(
    var oilMoney: Map<String, Double> = mapOf(),
    var mail: String = "",
    var medalHalfYear: Boolean = false
)

Upvotes: 0

R...
R...

Reputation: 2620

in your original code changing this line

doc.update({foo: "bar"})

to this

doc.ref.update({foo: "bar"})

should work

but a better way is to use batch write: https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes

Upvotes: 20

Ronnie Smith
Ronnie Smith

Reputation: 18585

Check if the user is already there then simply .update, or .set if not:

    var docRef = firebase.firestore().collection("users").doc(firebase.auth().currentUser.uid);
    var o = {};
    docRef.get().then(function(thisDoc) {
        if (thisDoc.exists) {
            //user is already there, write only last login
            o.lastLoginDate = Date.now();
            docRef.update(o);
        }
        else {
            //new user
            o.displayName = firebase.auth().currentUser.displayName;
            o.accountCreatedDate = Date.now();
            o.lastLoginDate = Date.now();
            // Send it
            docRef.set(o);
        }
        toast("Welcome " + firebase.auth().currentUser.displayName);
    });
}).catch(function(error) {
    toast(error.message);
});

Upvotes: 26

Related Questions