尝试从 Firestore 获取和更新集合时发现“文档集合中未定义”
Posted
技术标签:
【中文标题】尝试从 Firestore 获取和更新集合时发现“文档集合中未定义”【英文标题】:Found "Undefined in Document Collection" when try to fetch and update Collection from Firestore 【发布时间】:2020-03-22 18:49:16 【问题描述】:我还是新手,还在使用 react 和 firebase 进行自学,请帮我处理这段代码。
我尝试使用带有 react 和 material-ui 的表单从 firestore 收集数据 获取和更新数据 ,
在我更新 useEffect 函数后,没有发现错误,只是没有按我的预期工作。
attached file firestore location picture
import React, useState, useEffect from 'react';
// material-ui
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
// firebase
import useFirebase from '../../../components/FirebaseProvider';
import useDocument from 'react-firebase-hooks/firestore';
import AppPageLoading from '../../../components/AppPageLoading';
import useSnackbar from 'notistack';
函数
function EditProduk( match )
const firestore, user = useFirebase();
const enqueueSnackbar = useSnackbar();
const produkTraining = firestore.doc(`userdoc/$user.uid/training/$match.params.trainingId`);
const [snapshot, loading] = useDocument(produkTraining);
const [form, setForm] = useState(
name: '',
trainer: '',
price: 0,
description: ''
);
const [error, setError] = useState(
name: '',
trainer: '',
price: '',
description: ''
)
const [isSubmitting, setSubmitting] = useState(false);
useEffect(() =>
if (snapshot)
setForm(currentForm => (
...currentForm,
...snapshot.data()
));
, [snapshot]);
const handleChange = e =>
setForm(
...form,
[e.target.name]: e.target.value
)
setError(
...error,
[e.target.name]: ''
)
const validate = () =>
const newError = ...error ;
if (!form.name)
newError.name = 'Training name must be filled';
if (!form.trainer)
newError.trainer = 'trainer name must be filled';
if (!form.price)
newError.price = 'price must be filled';
if (!form.description)
newError.description = 'description must be filled';
return newError
const handleSubmit = async e =>
e.preventDefault();
const findErrors = validate();
if (Object.values(findErrors).some(err => err !== ''))
setError(findErrors);
else
setSubmitting(true);
try
await produkTraining.set(form, merge: true );
enqueueSnackbar('Data has been saved', variant: 'success' )
catch (e)
enqueueSnackbar(e.message, variant: 'error' )
setSubmitting(false);
if (loading)
return <AppPageLoading />
return <div>
<Typography variant="h5" component="h1">Edit Training: form.name</Typography>
<Grid container alignItems="center" justify="center">
<Grid item xs=12 sm=6>
<form id="produk-form" onSubmit=handleSubmit noValidate>
<TextField
id="name"
name="name"
label="Training Name"
margin="normal"
required
fullWidth
value=form.name
onChange=handleChange
helperText=error.name
error=error.name ? true : false
disabled=isSubmitting
/>
firestore 规则
service cloud.firestore
match /databases/database/documents
match /userdoc/uid
allow read: if request.auth.uid == uid;
allow write: if request.auth.uid == uid;
match /training/trainingId
allow read, write: if request.auth.uid == uid;
请给我一些建议
【问题讨论】:
@AtinSingh 我不确定这个。签出此代码沙箱codesandbox.io/s/… 【参考方案1】:首先,如果你想测试firestore规则,有一个很好的选择(firestore模拟器,你可以在firebase consol中找到它)你可以在其中指定很多不同的参数并测试你是否可以访问数据或不基于特定场景。
据我了解,您希望从 firestore 获取数据,将其放入表单,可能会编辑数据并将其保存回数据库。
您收到的错误与 firestore 或其规则无关,因为目前似乎未定义 form
变量。
试试这个:
async function EditProduk( match )
...
const [snapshot, loading] = await useDocument(trainingDoc);
【讨论】:
是的,先生,我想从 Firestore 中获取数据,将其放入表单中,可能会编辑数据并将其保存回数据库 @jawara 我认为问题在于你不会等待 useDocument,所以我猜在那一行之后,useEffect 会将表单变量设置为未定义。为此使用异步操作。【参考方案2】:要消除错误,您需要将value=form.name
替换为value=form && form.name && form.name
还有
useEffect(() =>
if (snapshot.exists)
setForm(snapshot.data());
, [snapshot]);
【讨论】:
获取数据是一个单独的问题。为了帮助解决这个问题,请打开一个新问题并向我们展示useFirebase()
和 useDocument()
如何工作并记录 match.params.trainingId
,以便我们知道这是一个有效的参考。
我说你是对的先生,但我仍然没有找到解决方案,你可以看到我附上的图片,不是针对 ID 集合,而是使用“未定义”集合 ID 创建一个新的集合 ID
您刚刚更改了整个问题?那不酷。如果我回答了您的原始问题,请授予我答案并打开一个新问题。你不能只是不断地改变你的问题,所有的回答对于以后阅读这篇文章的任何人来说都是断章取义的。我不赞成。以上是关于尝试从 Firestore 获取和更新集合时发现“文档集合中未定义”的主要内容,如果未能解决你的问题,请参考以下文章
大型集合的 Firestore DeadlineExceeded 异常