In an ionic vue app, I want to display some data from a Firebase Firestore in.
In the Firestore, I have a collection households
with a subcollection entries
. A user can be a member of a household and I want to display all entries of all households she is a member of.
I have an array entries
in my data
:
data() {
return {
entries: [],
};
},
I fill this array by making three nested queries against firebase:
- Get current user
- Get all households associated with current user
- Get all entries from all households for current user
beforeCreate: function () {
auth.onAuthStateChanged((user) => {
if (user) {
// Get current uid
let uid = user.uid;
// Loop trough all households of user
let userHouseholdIds = [];
db.collection("households")
.where("members", "array-contains", uid)
.onSnapshot((snapshotChange) => {
snapshotChange.forEach((doc) => {
userHouseholdIds.push(doc.id);
});
userHouseholdIds.forEach((householdId) => {
// Get household name
db.collection("households")
.doc(householdId)
.get()
.then((value) => {
let householdId = value.id;
let householdName = value.data().name;
// Get household entries
db.collection("households")
.doc(householdId)
.collection("entries")
.onSnapshot((snapshotChange) => {
snapshotChange.forEach((doc) => {
let newDoc = doc.data();
newDoc["id"] = doc.id;
newDoc["householdName"] = householdName;
newDoc["householdId"] = householdId;
this.entries.push(newDoc);
});
});
});
});
});
}
});
Although I'm not sure if this is the way to go, this works as expected (so far).
However, when I make a change in an entry e1
in a household h1
directly in the Firestore console, every entry from h1
gets duplicated in the frontend.
I guess, I need a this.entries = []
somewhere before an update from Firestore comes in, but I cannot figure out where.
Am I on the right track? What would I need to modify to avoid the duplication? Thanks a lot!
CodePudding user response:
if you have to use 'onSnapshot' check change.type
db
.collection(...)
.where(...)
.onSnapshot((snapshotChange) => {
snapshotChange.docChanges().forEach(change => {
if (change.type === 'added') {
this.entries.push()
} else if (change.type === 'modified') {
this.entries.splice()
} else if (change.type === 'removed') {
this.entries.splice()
}
})
})
If not, try using get()
db
.collection(...)
.where(...)
.get()