问题
I'm trying to get all documents from a firebase collection, create a list and return it on request with a Cloud Function, but I'm struggling with the asynchronous nature of JavaScript. Here's my code so far:
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
const items = "";
async function buildItems() {
db.collection("reminders").get().then((QuerySnapshot) => {
QuerySnapshot.forEach((item) => {
items.concat("<li>" + item.data().name + "</li>");
console.log(items);
});
})
}
exports.view = functions.https.onRequest((req, res) => {
buildItems().then(
res.status(200).send(`<!doctype html>
<head>
<title>Reminders</title>
</head>
<body>
<ul>
${items}
</ul>
</body>
</html>`))});
EDIT: Include Promises-based code I've tried (it's wrong, I don't know how to solve it)
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
function buildItems() {
return new Promise((resolve) => {
resolve(db.collection("reminders").get())
});
}
exports.view = functions.https.onRequest((req, res) => {
buildItems(reminders => {
let items = "";
reminders.then((qs) => {
qs.forEach(items.concat("<li>" + qs.data().name + "</li>"))
}).then(resolve(items));
}).then( items =>
res.status(200).send(`
<!doctype html>
<head>
<title>Reminders</title>
</head>
<body>
<ul>
${items}
</ul>
</body>
</html>`))});
The output is always the same: absolutely nothing is displayed on the browser or to the console. I've tried variations of this code, but no success so far.
Thanks in advance!
回答1:
I cleaned the code up a bit and replaced your Promise based code with async await. You can try running this:
async await version
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
const buildItems = async () => {
return db.collection('reminders').get();
};
exports.view = functions.https.onRequest(async (req, res) => {
try {
const reminders = await buildItems();
let items = '';
reminders.forEach(qs => {
items.concat(`<li> ${qs.data().name} </li>`);
});
return res
.status(200)
.send(`
<!doctype html>
<head>
<title>Reminders</title>
</head>
<body>
<ul>
${items}
</ul>
</body>
</html>
`);
} catch (error) {
/** Handle error here */
}
});
Promise based version
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
const buildItems = () => {
return db.collection('reminders').get();
};
exports.view = functions.https.onRequest((req, res) => {
buildItems()
.then(reminders => {
let items = '';
reminders.forEach(qs => {
items.concat(`<li> ${qs.data().name} </li>`);
});
return res
.status(200)
.send(`
<!doctype html>
<head>
<title>Reminders</title>
</head>
<body>
<ul>
${items}
</ul>
</body>
</html>
`);
})
.catch(error => {
/** Handle Error here */
});
});
If you are having still having trouble, you should try if the collection reminders actually contains the documents you want to fetch.
The .size property is available in [QuerySnapShots][1] in Firebase query snapshot results. If the snapshot size is 0.
来源:https://stackoverflow.com/questions/58158537/asynchronous-firebase-query-to-response