Angular: 4.3
Firebase: 4.5.0
AngularFire: 5.0 rc1
Other (e.g. Ionic/Cordova, Node, browser, operating system):
https://stackblitz.com/edit/angular-abcgfq?file=app%2Fapp.component.ts
I think stackblitz is having trouble with the AngularFire2 import, if you get the red squiggly under angularfire2/firestore go to dependencies, delete the library and re-install
Steps to set up and reproduce
Create an AngularFirestoreDocument call .update() on it with a single field (of a larger object) and it is not accepted.
Sample data and security rules n/a
<-- include/attach/link to some json sample data (or provide credentials to a sanitized, test Firebase project) -->
* Errors in the JavaScript console *
* Output from firebase.database().enableLogging(true); *
* Screenshots *
I would expect that I can update a single field on a larger object as per the Firestore docs
Typescript is telling me:
Argument of type '{ votes: number; }' is not assignable to parameter of type 'Post'.
Property 'text' is missing in type '{ votes: number; }'.
That is to say, "We're looking for you to pass in the whole Post object, not just one field."
Not only the partial typescript issue but it appears .update() is not creating a document if it doesn't already exist. .set() works.
const path = `users/${this.currentUserId}`; // Endpoint on firebase
this.userDocument = this.afs.doc<any>(path);
const data = {
email: this.authState.email,
name: this.authState.displayName
}
this.userDocument.update(data) // .set() works correctly right here...
.catch(error => console.log(error));
}
According to the Node.js documentation for "Set a document" at https://firebase.google.com/docs/firestore/manage-data/add-data:
The option to merge data is not yet available for Node.js. Instead, call the update method and pass the option to create the document if it's missing.
I couldn't find that feature documented anywhere, but tried appending "create: true" to the update request and it works swimmingly.
// Updates "widget-1" doc if it exists, or creates it if it doesn't
db.collection('widgets').doc('widget-1').update({
thingamajig: true
}, { create: true });
@itjustwerks can you tell me why using create: true I get [ts] Expected 1 arguments, but got 2. from my linter? What could it be that I have different from you?
"angularfire2": "^5.0.0-rc.3",
"firebase": "^4.5.2"
constructor(
private db: AngularFirestore
)
const userRef: AngularFirestoreDocument<any> = this.db.collection('users').doc(user.uid);
const data: User = {
// some data
};
return userRef.update(data, { create: true });
Ok I got it:
[...]
const userRef = this.db.firestore.collection('users').doc(user.uid);
[...]
return userRef
.get()
.then(doc => {
if (!doc.exists) {
userRef.set(data);
} else {
userRef.update(data);
}
})
.catch(err => {
console.log(`[LOGIN] ${err}`);
});
[...]
@Azmos , my bad. The {create: true} 2nd parameter is only applicable to the firebase-admin Node.js library for some reason. I just tried it myself for the web today and got the same error as you. I ended up doing the set in the catch block if there was an error on the update, but your solution is better for sure. Thanks!
It seems you can also do:
userRef.set(data, {merge: true});
As documented here: https://firebase.google.com/docs/firestore/manage-data/add-data
Am I missing something which would make this different than update(data, {create: true})?
EDIT: Nevermind, this project uses the NodeJS client instead of the web client. (odd that they would implement set(...{merge: true}) in one, and update(...{create: true}) in the other)
Tried once again and neither of them work on my code, in my case checking "manually" if the document exists is the only way to achieve that.
Tried once again and neither of them work on my code, in my case checking "manu
Most helpful comment
It seems you can also do:
As documented here: https://firebase.google.com/docs/firestore/manage-data/add-data
Am I missing something which would make this different than
update(data, {create: true})?EDIT: Nevermind, this project uses the NodeJS client instead of the web client. (odd that they would implement
set(...{merge: true})in one, andupdate(...{create: true})in the other)