Reputation: 2837
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
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
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.
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
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
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
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
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
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
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