Return 反应中的 firestore onSnapshot 值
Return value firestore onSnapshot in react
我在函数中有一个 onSnapshot 查询:
//firebaseutil.js
export async function getShorts(uid) {
const q = query(collection(db, 'shorted'), where('owner', '==', uid));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const urls = [];
querySnapshot.forEach((doc) => {
urls.push({
url: doc.data().url,
shorturl: doc.data().shorturl,
hits: doc.data().hits,
});
});
console.log(urls);
return urls;
});
}
正确记录数据,如果我在 firestore 集合上更改它(如预期),则重新记录它
我正在尝试以这种方式从用户仪表板访问这些数据:
//dashboard.js
import { getShorts } from '../lib/fbutils';
import { useEffect, useState } from 'react';
export default function Dashboard() {
const [myurls, setUrls] = useState([]);
useEffect(() => {
const fetchShorts = async () => {
if (user) {
const urls = await getShorts(user.uid);
setUrls(urls);
console.log(myurls);
console.log(urls);
}
};
fetchShorts();
}, []);
user.id 设置正确,但 urls 和 myurls 都记录为未定义(我至少在考虑 Promise pending)
我做错了什么?我通常使用这种模式来检索数据,但这是我第一次从 firestore 订阅中获取数据
onSnapshot()
没有 return 承诺,您的 getShorts()
功能在 return 收到数据之前。您可以 return 来自该函数的承诺,如下所示:
let fetched = false;
export function getShorts(uid) {
return new Promise((resolve, reject) => {
const q = query(collection(db, 'shorted'), where('owner', '==', uid));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const urls = querySnapstho.docs.map((d) => ({ id: d.id, ...d.data() }))
if (!fetched) {
// URLs fetched for first time, return value
fetched = true;
resolve(urls);
} else {
// URLs fetched already, an update received.
// TODO: Update in state directly
}
})
})
}
当您调用函数 await getShorts(user.uid);
时,这应该 return 所有 URL,但对于稍后收到的更新,您必须直接在状态下更新它们,因为承诺现在已解决。
我在函数中有一个 onSnapshot 查询:
//firebaseutil.js
export async function getShorts(uid) {
const q = query(collection(db, 'shorted'), where('owner', '==', uid));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const urls = [];
querySnapshot.forEach((doc) => {
urls.push({
url: doc.data().url,
shorturl: doc.data().shorturl,
hits: doc.data().hits,
});
});
console.log(urls);
return urls;
});
}
正确记录数据,如果我在 firestore 集合上更改它(如预期),则重新记录它
我正在尝试以这种方式从用户仪表板访问这些数据:
//dashboard.js
import { getShorts } from '../lib/fbutils';
import { useEffect, useState } from 'react';
export default function Dashboard() {
const [myurls, setUrls] = useState([]);
useEffect(() => {
const fetchShorts = async () => {
if (user) {
const urls = await getShorts(user.uid);
setUrls(urls);
console.log(myurls);
console.log(urls);
}
};
fetchShorts();
}, []);
user.id 设置正确,但 urls 和 myurls 都记录为未定义(我至少在考虑 Promise pending)
我做错了什么?我通常使用这种模式来检索数据,但这是我第一次从 firestore 订阅中获取数据
onSnapshot()
没有 return 承诺,您的 getShorts()
功能在 return 收到数据之前。您可以 return 来自该函数的承诺,如下所示:
let fetched = false;
export function getShorts(uid) {
return new Promise((resolve, reject) => {
const q = query(collection(db, 'shorted'), where('owner', '==', uid));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
const urls = querySnapstho.docs.map((d) => ({ id: d.id, ...d.data() }))
if (!fetched) {
// URLs fetched for first time, return value
fetched = true;
resolve(urls);
} else {
// URLs fetched already, an update received.
// TODO: Update in state directly
}
})
})
}
当您调用函数 await getShorts(user.uid);
时,这应该 return 所有 URL,但对于稍后收到的更新,您必须直接在状态下更新它们,因为承诺现在已解决。