Firestore代码报错TypeError: Cannot read property 'then' of undefined求解答
Hey there, let's break down why you're hitting this error and how to fix it step by step.
Why the Error Happens
The root issue comes down to two key problems:
forEachdoesn’t return a Promise — When you runquerySnapshot.forEach(...), it loops through your documents but returnsundefined. Trying to chain a.then()right after it throws an error becauseundefineddoesn’t have athenmethod.- Broken Promise chain — Inside the
forEachcallback, you’ve got nested async operations (anonymous sign-in, fetching the download URL) but aren’t returning them properly. This means the outer Promise chain doesn’t wait for these async tasks to finish, leading to unexpected behavior and broken chaining.
What Does "Return a Promise" Mean?
Promises are JavaScript’s way of handling async work (like fetching data from Firestore or Storage). When you’re using a chain of .then() calls, each .then() expects the previous step to return either a plain value or a Promise. If you return a Promise, the next .then() waits for that Promise to resolve before running. If you don’t return anything (or return undefined), the chain breaks — which is exactly what’s happening here.
Fixed Code Example
Let’s rewrite your code to fix these issues:
firestore.collection("products").where("OrderNo", "==", inputx) .get() .then(function(querySnapshot) { // Use map instead of forEach to collect all async tasks as Promises const documentTasks = querySnapshot.docs.map(function(doc) { const Nameout = doc.get("Name"); const path = `products/${inputx}-${Nameout}`; const tangRef = storageRef.child(path); // Return the full Promise chain so map can collect it return firebase.auth().signInAnonymously() .then(function() { // Return the download URL Promise to continue the chain return tangRef.getDownloadURL(); }) .then(function(url) { // Fix the selector: use #img1 for ID, .img1 for class document.querySelector('#img1').src = url; }) .catch(function(error) { console.error(`Error processing document ${doc.id}:`, error); }); }); // Wait for all document tasks to finish before moving to the next then() return Promise.all(documentTasks); }) .then(function() { console.log("All product images loaded successfully!"); }) .catch(function(error) { console.error("Error fetching products from Firestore:", error); });
Key Fixes Explained
- Swapped
forEachformap:mapcreates an array of Promises (one for each document’s async workflow). We usePromise.all()to wait for all these Promises to resolve, which gives us a valid Promise to return to the outer chain. - Returned inner Promises: Each async step (
signInAnonymously,getDownloadURL) is returned so the Promise chain stays connected. This ensures each operation waits for the previous one to finish. - Fixed DOM selector:
document.querySelector('img1')is invalid — use#img1if your image has an ID ofimg1, or.img1if it’s a class. - Targeted error handling: Split catch blocks to handle errors at different stages (fetching products, processing individual documents) for easier debugging.
This should resolve the "Cannot read property 'then' of undefined" error and make your async operations run in a predictable, reliable order.
内容的提问来源于stack exchange,提问作者Paul Baiju

