[英]Nextjs getStaticPaths not fetching data from firebase firestore
[英]Fetching data after forEach() from Firestore in Javascript
我正在構建一個鍛煉 web 應用程序,需要顯示每次鍛煉要完成多少輪以及每輪有多少鍛煉。
由於每次鍛煉的輪數和每輪鍛煉都不同,因此我將它們設置為 forEach。
但我需要知道回合集合的 docID(顯示為“roundID”)才能獲得特定的 collections,子集合以顯示特定的練習。
目前它沒有顯示練習,因為我需要等待第一次提取完成,然后使用我無法做到的那個 docId。
我已經嘗試使用循環等待,異步但無法讓它工作。
目前我的代碼是:
Main forEach 獲得回合
const Rnds = document.getElementById("rnds");
const roundRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds"));
const unsub = onSnapshot(roundRef, (querySnapshot) => {
querySnapshot.forEach((doc) => {
const roundID = doc.id;
const rounds = doc.data().round;
const rests = doc.data().rest;
console.log("Round", roundID);
Rnds.innerHTML += `
<h2>${rounds}</h2>
A list of the amount of exercise docs in "exercise" collection
<p>${rests}</p>
`
});
});
然后,獲取輪次的練習
const exerciseRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds", roundID, "exercises"));
const exerciseUnsub = onSnapshot(exerciseRef, (querySnapshot) => {
querySnapshot.forEach((doc) => {
const reps = doc.data().rep;
const names = doc.data().exerciseName;
console.log("Exercises", doc.data());
});
});
目前我可以獲取 go 的回合和正確的練習文檔,並顯示在控制台中。 我設法讓回合顯示但無法將練習名稱傳遞給 innerHTML。
// Create Exercise Rounds
const Rnds = document.getElementById("rnds");
const roundRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds"));
const roundsUnsub = onSnapshot(roundRef, (querySnapshot) => {
querySnapshot.forEach((doc) => {
const DocId = doc.id;
const rounds = doc.data().roundName;
const rests = "Rest: " + doc.data().rest;
// Calls the `runQuery` async function to get the exercises documents.
runQuery(DocId).then((result) => {
// Initialized an object
const obj = {};
const names = obj.exerciseNames;
// Assigns the exercises' documents data to its round collection's documents' Id.
obj[DocId] = result;
// Logs the constructed object.
console.log(obj);
// Put your `innerhtml` here.
Rnds.innerHTML += `
<h2>${rounds}</h2>
<p>${names}</p>. // <- unable to get this to show
<p>${rests}</p>
`
});
});
});
async function runQuery(documentId) {
const exerciseRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds", documentId, "exercises"));
const querySnapshot = await getDocs(exerciseRef);
if (!querySnapshot) {
return null;
}
// Returns a map of data (array).
return querySnapshot.docs.map((doc) => doc.data());
}
roundsUnsub;
有一種方法可以關聯或獲取練習集的數據,但有幾點我想指出:
onSnapshot
只監聽你在這行代碼中查詢的所有文檔的變化(即rounds集合中的文檔): const roundRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds"));
要從回合集合中獲取實時更新並將練習關聯到回合的文檔,則必須創建一個異步 function,您應該在主 function 上調用它。請參見下面的代碼示例:
const roundRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds"));
const unsub = onSnapshot(roundRef, (querySnapshot) => {
querySnapshot.forEach((doc) => {
const DocId = doc.id;
// Calls the `runQuery` async function to get the exercises documents.
runQuery(DocId).then((result) => {
// Initialized an object
const obj = {};
// Assigns the exercises' documents data to its round collection's documents' Id.
obj[DocId] = result;
// Logs the constructed object.
console.log(obj);
// Put your `innerhtml` here.
});
});
});
async function runQuery(documentId) {
const exerciseRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds", documentId, "exercises"));
const querySnapshot = await getDocs(exerciseRef);
if (!querySnapshot) {
return null;
}
// Returns a map of data (array).
return querySnapshot.docs.map((doc) => doc.data());
}
我添加了一些注釋以更好地理解上面的代碼。
正如我在上面指出的一些問題,如果你想從你的回合集合中獲得實時更新,可以有一些解決方法。 您必須修改添加、更新或刪除文檔的方式。 首先,您需要向練習集合中添加一個文檔,然后將數據更新或設置到新創建的回合的文檔中。 請參閱下面的示例代碼:
// Your document ID for rounds collection
const docId = 'Round 3';
const exercisesRef = collection(db, 'user', uid, 'yourWorkouts', id, 'rounds', docId, 'exercises');
const roundsRef = doc(db, 'users', uid, 'yourWorkouts', id, 'rounds', docId);
// Add a document to the rounds and exercises collection. Sets the data to the exercises document.
addDoc(exercisesRef, {
// Your exercises document data
}, { merge: true })
.then (() => {
// Method above will create a round document but doesn't have data on it (still an invalid document).
// We need to set or update the document to make it a valid document to be able for a snapshot to read the newly added document.
setDoc(roundsRef, {
// Your Rounds document data
}, { merge: true })
.catch((error) => {
console.error("Error writing Rounds document: ", error);
});
})
.catch((error) => {
console.error("Error writing exercises document: ", error);
});
有關更多相關信息,您可能需要查看此文檔:
更新:
根據您呈現數據的方式,您只需將 object 分配給一個變量,該變量又返回undefined
。 您必須先訪問 object 並使用for
循環,因為練習 collections 可以有多個文檔。 請參閱下面的代碼:
// Create Exercise Rounds
const Rnds = document.getElementById("rnds");
const roundRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds"));
const roundsUnsub = onSnapshot(roundRef, (querySnapshot) => {
querySnapshot.forEach((doc) => {
const DocId = doc.id;
const rounds = doc.data().roundName;
const rests = "Rest: " + doc.data().rest;
// Calls the `runQuery` async function to get the exercises documents.
runQuery(DocId).then((result) => {
// Initialized an object
const obj = {};
// Assigns the exercises' documents data to its round collection's documents' Id.
obj[DocId] = result;
// Initialize names array to be used in `innerhtml`
const names = [];
// Logs the constructed object.
console.log(obj);
// Loops your exerciseNames and push it in the `names` array
for (const exerciseDocument of obj[DocId]) {
names.push(exerciseDocument.exerciseNames);
}
// Put your `innerhtml` here.
Rnds.innerHTML += `
<h2>${rounds}</h2>
<p>${names}</p>. // This will now show
<p>${rests}</p>
`
});
});
});
async function runQuery(documentId) {
const exerciseRef = query(collection(db, "user", uid, "yourWorkouts", id, "rounds", documentId, "exercises"));
const querySnapshot = await getDocs(exerciseRef);
if (!querySnapshot) {
return null;
}
// Returns a map of data (array).
return querySnapshot.docs.map((doc) => doc.data());
}
roundsUnsub;
要分隔名稱,而不是將名稱推入數組,您需要初始化一個字符串並使用<p>
標記迭代 html output 並使用+=
(加法賦值運算符)將結果賦給變量。 請參閱下面的代碼:
runQuery(DocId).then((result) => {
// Initialized an object
const obj = {};
// Assigns the exercises' documents data to its round collection's documents' Id.
obj[DocId] = result;
var names = "";
for (const exerciseDocument of obj[DocId])
// Make sure that you type the fieldname correctly.
// Based on your codes given above, you mentioned `exerciseName` and `exerciseNames`
names +=`<p>${exerciseDocument.exerciseNames}</p>`;
}
Rnds.innerHTML +=
`<h2>${rounds}</h2>.
${names}.
<p>${rests}</p>`
});
});
查看此工作片段。 它應該是這樣的:
<.DOCTYPE html> <html> <body> <p id="rnds"></p> <script> const Rnds = document;getElementById("rnds"); const DocId = 'Round' const rounds = DocId: // Sample constructed object based on your Firestore Structure const obj = {Round:[{exerciseNames, 'exercise1'}: {exerciseNames; 'exercise2'}]}; const rests = 'testRest'. var names = "" for (const exerciseDocument of obj[DocId]) { names +=`<p>${exerciseDocument;exerciseNames}</p>`. } Rnds.innerHTML += `<h2>${rounds}</h2>. ${names}. <p>${rests}</p>` </script> </body> </html>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.