I'm trying to get an array of changes using Firebase Firestore's onShapshot().
I'm having trouble retrieving data through onSnapshot()
; I may be in trouble with async/await
as well, not quite sure...
Can you see where there are problems?
Output should be (but it is currently):
1. New friends: ... // via onSnapshot(). Should not be empty, but it is (However, it does get populated afterwards).
2. All friends: ... // Should not be empty, but it is.
3. Fred's friends: ... // Should not be empty, but it is.
Code:
const getAllFriends = async () => {
// Gets all friends by connecting to Firestore's onSnapshot stream.
const getNewFriends = async () => {
// Sets up a onSnapshot() stream, and returns a newFriends array with their names.
// Problem: It initially return an empty array, when it shouldn't be empty.
let newFriends = [];
await db.collection("user").doc("john").collection("friends").onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
newFriends.push({ friend: "Emily" });
});
});
console.log("1. New friends: ", newFriends, newFriends.length); // Length should not be 0.
return newFriends;
}
// John starts with no friends:
let friends = [];
// John should now have found some friends:
let friendChanges = await getNewFriends();
friends = friends.concat(friendChanges);
console.log("2. All friends:", friends); // Should contain a few Emilys.
return friends;
};
let johnFriends = await getAllFriends();
console.log("3. John's friends:", friends); // Should contain a few Emilys.
I'm trying to get an array of changes using Firebase Firestore's onShapshot().
I'm having trouble retrieving data through onSnapshot()
; I may be in trouble with async/await
as well, not quite sure...
Can you see where there are problems?
Output should be (but it is currently):
1. New friends: ... // via onSnapshot(). Should not be empty, but it is (However, it does get populated afterwards).
2. All friends: ... // Should not be empty, but it is.
3. Fred's friends: ... // Should not be empty, but it is.
Code:
const getAllFriends = async () => {
// Gets all friends by connecting to Firestore's onSnapshot stream.
const getNewFriends = async () => {
// Sets up a onSnapshot() stream, and returns a newFriends array with their names.
// Problem: It initially return an empty array, when it shouldn't be empty.
let newFriends = [];
await db.collection("user").doc("john").collection("friends").onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
newFriends.push({ friend: "Emily" });
});
});
console.log("1. New friends: ", newFriends, newFriends.length); // Length should not be 0.
return newFriends;
}
// John starts with no friends:
let friends = [];
// John should now have found some friends:
let friendChanges = await getNewFriends();
friends = friends.concat(friendChanges);
console.log("2. All friends:", friends); // Should contain a few Emilys.
return friends;
};
let johnFriends = await getAllFriends();
console.log("3. John's friends:", friends); // Should contain a few Emilys.
Share
Improve this question
edited Apr 15, 2023 at 8:37
Renaud Tarnec
83.2k10 gold badges98 silver badges129 bronze badges
Recognized by Google Cloud Collective
asked Oct 25, 2020 at 8:29
daCodadaCoda
3,8655 gold badges36 silver badges40 bronze badges
2
- If you only need to retrieve data then don't use onSnapshot() function instead use .get() method then async await will might work. – Zuhair Naqi Commented Oct 25, 2020 at 8:46
- 1 did you find an answer to this issue? I seem to be having similar issue. – Penguin Commented Jul 5, 2021 at 14:40
2 Answers
Reset to default 3Have a look at this answer which explains the difference between the get()
and onSnapshot()
methods.
In a nutshell:
- When you use
get()
you retrieve all the documents of the collection only once (like a "get and forget"). - When you use
onSnapshot()
you constantly listen to the collection.
Note that onSnapshot()
is not an asynchronous method, while get()
is => don't call onSnapshot()
with await
.
Since, from your question, it seems that you want to get the list of friends by calling the getAllFriends()
method, do as follows:
const getAllFriends = async (userName) => {
const querySnapshot = await db
.collection('user')
.doc(userName)
.collection('friends')
.get();
return querySnapshot;
};
let johnFriends = await getAllFriends('john');
johnFriends.forEach(doc => {
console.log(doc.id, ' => ', doc.data());
});
More possibilities are to be found in the Firestore doc, here and here.
I think you just want to track newly added John's friends and add them to the johnFiends
array. Perhaps you can just add the onsnapshot
listener on top of @Renaud's suggestion:
const getAllFriends = async (userName) => {
const querySnapshot = await db
.collection('user')
.doc(userName)
.collection('friends')
.get();
// You may need check for querySnapshot.empty before proceed
let allFriends = querySnapshot.docs.map(doc => doc.data());
return allFriends;
};
let johnFriends = await getAllFriends('john');
console.log("All John's friends:", johnFriends);
const unsubscribe = db.collection("user").doc("john").collection("friends")
.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
if (change.type === "added") {
johnFriends.push(change.doc.data());
console.log("New John's friend:", change.doc.data());
console.log("New all John's friends:", johnFriends);
};
});
});
Note that onsnapshot
is mostly for real-time tracking of data change at the backend and what you should do later in the frontend, therefore you should apply it on real-time handler instead of incorporate it inside a normal data pulling function, e.g. getAllFriends()
. In short, handle real-time changes separately.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742418897a4440283.html
评论列表(0条)