Javascript 了解何时何地需要使用onAuthStateChanged()-Firebase/Next.js
这是从示例(Next.js)构建的项目的index.js页面Javascript 了解何时何地需要使用onAuthStateChanged()-Firebase/Next.js,javascript,google-cloud-firestore,firebase-authentication,next.js,Javascript,Google Cloud Firestore,Firebase Authentication,Next.js,这是从示例(Next.js)构建的项目的index.js页面 const Index=()=>{ const{user,logout}=useUser(); 如果(!用户){ 返回( 试验 您尚未登录。{“”} 登录 ); } 返回( ); }; 出口违约指数; 客户端组件用于列出一组firestore文档。以下是组件的编写方式: const Clients = () => { const { user, logout } = useUser(); const [cl
const Index=()=>{
const{user,logout}=useUser();
如果(!用户){
返回(
试验
您尚未登录。{“”}
登录
);
}
返回(
);
};
出口违约指数;
客户端组件用于列出一组firestore文档。以下是组件的编写方式:
const Clients = () => {
const { user, logout } = useUser();
const [clients, setClients] = useState([]);
var userRef = firebase.auth().currentUser;
useEffect(() => {
firebase.firestore()
.collection('users')
.doc(userRef.uid)
.collection('clients')
.onSnapshot(snap => {
const clients = snap.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
setClients(clients);
});
}, []);
return (
<div>
<ul>
{clients.map(client =>
<li key={client.id}>
{client.name}
</li>
)}
</ul>
</div>
);
};
export default Clients;
const客户端=()=>{
const{user,logout}=useUser();
const[clients,setClients]=useState([]);
var userRef=firebase.auth().currentUser;
useffect(()=>{
firebase.firestore()
.collection('用户')
.doc(userRef.uid)
.collection(“客户”)
.onSnapshot(快照=>{
const clients=snap.docs.map(doc=>({
id:doc.id,
…文件数据()
}));
客户(客户);
});
}, []);
返回(
{clients.map(client=>
-
{client.name}
)}
);
};
导出默认客户端;
如果在index.js中,返回是以存在用户对象为条件的,那么在该返回中的客户端如何可以将“user”视为未定义
我尝试使用onAuthStateChanged()并尝试使用firebase.auth().currentUser来代替用户引用和user.uid-我不断遇到以下错误:
无法读取未定义的属性“uid”
未定义用户
客户端(…)返回空
我想我的问题的答案是“确保在尝试访问user.uid之前等待firebase auth”-但我似乎无法在客户端实现这一点
更新
当尝试使用onAuthStateChanged在尝试与其uid交互之前验证用户是否存在时,我遇到了一个错误“渲染的钩子比上次渲染时多”
分别地
实际上,我通过删除useEffect并将其写成这样,获得了(某种程度上)想要的效果:
const Clients = () => {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
const db = firebase.firestore();
db.collection('users')
.doc(user.uid)
.collection('clients')
.onSnapshot(snap => {
const clients = snap.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
setClients(clients);
});
} else {
[]
}
});
const [clients, setClients] = useState([]);
return (
<div>
<ul>
{clients.map(client =>
<li key={client.id}>
{client.name}
</li>
)}
</ul>
</div>
);
};
export default Clients;
const客户端=()=>{
firebase.auth().onAuthStateChanged(函数(用户){
如果(用户){
const db=firebase.firestore();
db.collection('用户')
.doc(user.uid)
.collection(“客户”)
.onSnapshot(快照=>{
const clients=snap.docs.map(doc=>({
id:doc.id,
…文件数据()
}));
客户(客户);
});
}否则{
[]
}
});
const[clients,setClients]=useState([]);
返回(
{clients.map(client=>
-
{client.name}
)}
);
};
导出默认客户端;
然而,这显然不像我注销时那样“正确”——我在控制台中收到大约30000条错误消息,上面说:
快照侦听器中的react_devtools_backend.js:2273未捕获错误:
FirebaseError:缺少或权限不足
但是,当我以任何用户身份登录时,我会得到正确呈现的列表,而不会出现控制台错误。用户/客户端集合是否不断变化?或者为什么要使用onSnapshot?是的,客户列表将定期(不一定经常)更改-客户最终也将有一个文档“记录”集合,这些文档将更新得更加频繁。在完成以下操作后,我将使用onSnapshot:
const Clients = () => {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
const db = firebase.firestore();
db.collection('users')
.doc(user.uid)
.collection('clients')
.onSnapshot(snap => {
const clients = snap.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
setClients(clients);
});
} else {
[]
}
});
const [clients, setClients] = useState([]);
return (
<div>
<ul>
{clients.map(client =>
<li key={client.id}>
{client.name}
</li>
)}
</ul>
</div>
);
};
export default Clients;