React Native firebase 如何 return 承诺列表

React native firebase how to return promise list

我编写了一个函数,可以按添加日期的顺序从 firestore 数据库中获取项目。内部 print 语句有效 - 它按预期打印出列表中的数据。但是,当我尝试调用该函数时,我得到了一个承诺。

async function fetch_recent_items(){
    const db = getFirestore(app);
    const col = collection(db, "my col")
    const q = query(col, orderBy("date", "asc"))

    const result = onSnapshot(q, (snapshot) => {
        items = [];
        snapshot.docs.forEach((doc) => {
            items.push(doc.data())
        })

        return items
    })
    console.log(items) // Prints list (desired result)
    return result 
    
}
console.log(fetch_recent_items()) // Prints promise

我如何处理这个承诺并从中检索数据?

Promise {
  "_U": 0,
  "_V": 0,
  "_W": null,
  "_X": null,
}

onSnapshot() 用于将 real-time 侦听器附加到特定数据位置。

但是,因为您正在尝试获取数据 on-demand,您应该使用 getDocs() 而不是只获取一次数据。

请记住,Firebase SDK 是异步 API。不要陷入这样的陷阱,即仅仅因为一条线在另一条线之上,它们就会以相同的顺序执行。这些 API 必须使用 .then.catchasync/await 适当地链接起来,此外还要确保 return 任何 Promise 链接到调用者。您可以阅读 Promises here and here, or even have a look at Web Dev Simplified's video series.

async function fetch_recent_items(){
    const db = getFirestore(app)
    const col = collection(db, "my col")
    const q = query(col, orderBy("date", "asc"))

    return getDocs(q)
        .then(querySnapshot => {
            return querySnapshot.docs // gets array of QueryDocumentSnapshot objects
                .map(doc => doc.data()) // consider using ({ id: doc.id, ...doc.data() }) instead
        })
}

fetch_recent_items()
    .then((items) => console.log(items))
    .catch((error) => console.error(error)) // don't forget error handling!

因为你在这里使用async,你可以稍微简化一下:

async function fetch_recent_items(){
    const db = getFirestore(app)
    const col = collection(db, "my col")
    const q = query(col, orderBy("date", "asc"))

    const querySnapshot = await getDocs(q);

    return querySnapshot.docs // gets array of QueryDocumentSnapshot objects
        .map(doc => doc.data()) // consider using ({ id: doc.id, ...doc.data() }) instead
}

// IF this is also in an async function, but don't make components async! - use useEffect/useAsyncEffect for that
try {
    const items = await fetch_recent_items();
    console.log(items)
} catch (error) {
    console.error(error) // don't forget error handling!
}