Angular: 7.2.0
Firebase: 5.8.2
AngularFire: 5.1.1
I am trying to update an array "likedPosts" for a User-Document:
User Model:
export interface User {
uid: string;
email: string;
photoURL?: string;
displayName?: string;
likedPosts?: string[];
createdPosts?: string[];
}
Update array:
const userRef: AngularFirestoreDocument<User> = this.afs.doc(
`users/${uid}`
);
userRef.update({
likedPosts: firestore.FieldValue.arrayUnion("post23")
});
I am getting the following error:
[ts] Type 'FieldValue' is missing the following properties from type 'string[]': length, pop, push, concat, and 26 more. [2740]
User.ts(6, 3): The expected type comes from property 'likedPosts' which is declared here on type 'Partial'
This is the example code from firebase.com:
var washingtonRef = db.collection("cities").doc("DC");
// Atomically add a new region to the "regions" array field.
washingtonRef.update({
regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia")
});
// Atomically remove a region from the "regions" array field.
washingtonRef.update({
regions: firebase.firestore.FieldValue.arrayRemove("east_coast")
});
test.firestore.js
Thank you for your help!
Typescript expects string[] and you provide a different type (arrayUnion does not return a string array)
I suggest to create a new interface called UserUpdate with FieldValue as the type, or add the FieldValue as a second type to regions: string[] | firebase.firestore.FieldValue
I solved this issue by importing firestore from firebase/app
import * as firebase from 'firebase/app';
then using it in update method
this.AngularFirestoreObj.doc('document-path')
.ref.update({ arrayField: firebase.firestore.FieldValue.arrayUnion(new_Item)})
Is there a proper/ community agreed upon way of doing this?
The suggestion of creating a new interface called with FieldValue does "work", however it feels like a hack and counter intuitive. Using this approach means you will have to set the AngularFirestoreCollection.doc method to one type when you are updating a document and another type when you are retrieving data from that same document.
@whoiscarlo I agree with you. Acctually if I follow this aproach I'll need to verify my variable with a typeof() a bunch of other places (every where I'm using a regions.length) to avoid another typing errors. Anyone has another solution to this situation?
Alright so this a complete HACK and I'm not necessarily recommending it, but since there's been no word from the contributors I might as well throw it out there for those like me who obsess over these kinds of things. Once again this is definitely a hack and can/will lead to confusion if you aren't extremely clear with how you orignize your data.
Using the original example from the author, I was able to "trick" the compiler by converting the _firebase.firestore.FieldValue_ element into an _unknown_ type then converting that type into the desired type, which in this case is _string[]_
firebase.firestore.FieldValue.arrayUnion('post23') as _unknown_ as _string[]_
Version 1
const userRef: AngularFirestoreDocument<User> = this.afs.doc(
'users/${uid}'
);
const addPost = firebase.firestore.FieldValue.arrayUnion('post23') as unknown as string[];
userRef.update({
likedPosts: addPost
});
Version 2
const userRef: AngularFirestoreDocument<User> = this.afs.doc(
'users/${uid}'
);
userRef.update({
likedPosts: firebase.firestore.FieldValue.arrayUnion('post23') as unknown as string[];
});
Most helpful comment
I solved this issue by importing firestore from
firebase/appimport * as firebase from 'firebase/app';then using it in update method
this.AngularFirestoreObj.doc('document-path') .ref.update({ arrayField: firebase.firestore.FieldValue.arrayUnion(new_Item)})