Since emojiCounter
is an array of Objects, you need to first read the Array, update it in the frontend then save it back to Firestore. Using the array-union()
method will not work, because it is an array of Objects.
You can verify that with the following code. The objects are added, not updated.
const db = firebase.firestore();
const docRef = db.collection('testSO').doc('testSO');
const emojiCounter = [
{ emoji: 'haha', by: 'user1' },
{ emoji: 'haha', by: 'user2' },
];
docRef
.set({ emojiCounter })
.then(() => {
return docRef.get();
})
.then((doc) => {
console.log('#1', doc.data().emojiCounter);
return docRef.update({
emojiCounter: firebase.firestore.FieldValue.arrayUnion({
emoji: 'hoho',
by: 'user1',
}),
});
})
.then(() => {
return docRef.get();
})
.then((doc) => {
console.log('#2', doc.data().emojiCounter);
return docRef.update({
emojiCounter: firebase.firestore.FieldValue.arrayUnion({
emoji: 'hihi',
by: 'user2',
}),
});
})
.then(() => {
return docRef.get();
})
.then((doc) => {
console.log('#3', doc.data().emojiCounter);
});
Note that you may encounter a problem with the solution described above, because, depending on your app functions, it may imply that user1
could change the emoji
value of user2
. If you want to avoid that, you should adopt another approach. For example allow the user to only update his emoji (e.g. with one emoji doc per user) and have a Cloud Function, triggered when one of those docs is updated, and which updates a central document which contains the array. You should use a Transaction to perform the update.
Also, since you are using one array that contains the emojis of all users, note the maximum size of a field value: 1,048,487 bytes.