Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firestore document .update() not working as intended #1245

Closed
markgoho opened this issue Oct 10, 2017 · 8 comments
Closed

Firestore document .update() not working as intended #1245

markgoho opened this issue Oct 10, 2017 · 8 comments

Comments

@markgoho
Copy link
Contributor

Version info

Angular: 4.3

Firebase: 4.5.0

AngularFire: 5.0 rc1

Other (e.g. Ionic/Cordova, Node, browser, operating system):

How to reproduce these conditions

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) -->

Debug output

** Errors in the JavaScript console **

** Output from firebase.database().enableLogging(true); **

** Screenshots **

Expected behavior

I would expect that I can update a single field on a larger object as per the Firestore docs

Actual behavior

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."

@LennyZ71
Copy link

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));
  }

@itjustwerks
Copy link

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 });

@ghost
Copy link

ghost commented Nov 1, 2017

@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 });

@ghost
Copy link

ghost commented Nov 2, 2017

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}`);
	});
[...]

@itjustwerks
Copy link

@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!

@Venryx
Copy link

Venryx commented Nov 27, 2017

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)

@ghost
Copy link

ghost commented Nov 28, 2017

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.

@lokesh75way
Copy link

Tried once again and neither of them work on my code, in my case checking "manu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants