Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs Formik、Material UI Autocomplete和Firestore-在何处查询以查找数组参数_Reactjs_Firebase_Google Cloud Firestore_Material Ui_Formik - Fatal编程技术网

Reactjs Formik、Material UI Autocomplete和Firestore-在何处查询以查找数组参数

Reactjs Formik、Material UI Autocomplete和Firestore-在何处查询以查找数组参数,reactjs,firebase,google-cloud-firestore,material-ui,formik,Reactjs,Firebase,Google Cloud Firestore,Material Ui,Formik,如何修改formik onChange处理程序,使其仅保存传递给Material UI Autocomplete字段的选项的值(而不是值加标签的数组) 我有一个集合,它有一个名为category属性的文档。当前,该类别将使用表单条目选项中的标签和值填充 我正在努力找到一种方法来获取firebase where查询,以查找数组的value属性 我想知道如果我尝试只保存值,而不是将标签和值都保存到firestore中,是否可以更接近一个有效的解决方案 我有一份Formik表格,上面有: impor

如何修改formik onChange处理程序,使其仅保存传递给Material UI Autocomplete字段的选项的值(而不是值加标签的数组)

我有一个集合,它有一个名为category属性的文档。当前,该类别将使用表单条目选项中的标签和值填充

我正在努力找到一种方法来获取firebase where查询,以查找数组的value属性

我想知道如果我尝试只保存值,而不是将标签和值都保存到firestore中,是否可以更接近一个有效的解决方案

我有一份Formik表格,上面有:

import React, { useState } from "react";
import ReactDOM from "react-dom";
import {render} from 'react-dom';

import { Link  } from 'react-router-dom';
import firebase, {firestore} from '../../../firebase';
import { withStyles } from '@material-ui/core/styles';

import {
  Button,
  LinearProgress,
  MenuItem,
  FormControl,
  Divider,
  InputLabel,
  FormControlLabel,
  TextField,
  Typography,
  Box,
  Grid,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentText,
  DialogTitle,
} from '@material-ui/core';
import MuiTextField from '@material-ui/core/TextField';


import {
  Formik, Form, Field, ErrorMessage, FieldArray,
} from 'formik';


import * as Yup from 'yup';
import {
  Autocomplete,
  ToggleButtonGroup,
  AutocompleteRenderInputParams,
} from 'formik-material-ui-lab';
import {
  fieldToTextField,
  TextFieldProps,
  Select,
  Switch,
  CheckboxWithLabel,
  Checkbox
} from 'formik-material-ui';


const allCategories = [
    {value: 'health', label: 'Health & Medical'},
    {value: 'general', label: 'General'},    
];


function UpperCasingTextField(props: TextFieldProps) {
    const {
      form: {setFieldValue},
      field: {name},
    } = props;
    const onChange = React.useCallback(
      event => {
        const {value} = event.target;
        setFieldValue(name, value ? value.toUpperCase() : '');
      },
      [setFieldValue, name]
    );
    return <MuiTextField {...fieldToTextField(props)} onChange={onChange} />;
  }

  function Summary(props) {
    const { classes } = props;
    const [open, setOpen] = useState(false);
    const [isSubmitionCompleted, setSubmitionCompleted] = useState(false);
    
    function handleClose() {
      setOpen(false);
    }
  
    function handleClickOpen() {
      setSubmitionCompleted(false);
      setOpen(true);
    }
  
    return (
      <React.Fragment>
          <Button
              // component="button"
              color="primary"
              onClick={handleClickOpen}
              style={{ float: "right"}}
              variant="outlined"
          >
              Create 
          </Button>
        <Dialog
          open={open}
          onClose={handleClose}
          aria-labelledby="form-dialog-title"
        >
          {!isSubmitionCompleted &&
            <React.Fragment>
              
              <DialogContent>
                <Formik
                  initialValues={{ title: "",  category: [], subcategory: "" }}
                  
                  onSubmit={(values, { setSubmitting }) => {
                     setSubmitting(true);
                     
                 
    firestore.collection("study").doc().set({
                      ...values,
                      createdAt: firebase.firestore.FieldValue.serverTimestamp()
                      })
                    .then(() => {
                      setSubmitionCompleted(true);
                    });
                  }}
  
                  validationSchema={Yup.object().shape({
                    title: Yup.string()
                      .required('Required'),
                    category: Yup.string()
                      .required('Required'),
                    
                  })}
                >
                  {(props) => {
                    const {
                      values,
                      touched,
                      errors,
                      dirty,
                      isSubmitting,
                      handleChange,
                      handleBlur,
                      handleSubmit,
                      handleReset,
                    } = props;
                    return (
                      <form onSubmit={handleSubmit}>
                        <TextField
                          label="Title"
                          name="title"
                          //   className={classes.textField}
                          value={values.title}
                          onChange={handleChange}
                          onBlur={handleBlur}
                          helperText={(errors.title && touched.title) && errors.title}
                          margin="normal"
                          style={{ width: "100%"}}
                        />

                        
                        <Box margin={1}>
                          <Field
                            name="category"
                            multiple
                            component={Autocomplete}
                            options={allCategories}
                            // value={values.label}
                            // value={values.value}
                            // value={allCategories.value} 
                           // value={values.category.allCategories.value}
注意-此操作用于查找标题。标题字段位于同一位置 级别作为类别字段

我已经看到了,但我不够聪明,无法从答案中理解任何意义

我也看到了贝蒂建议的答案。我尝试了以下查询构造的多个变体来尝试使用这个想法,但是每次,我都会在查询的形式上出错

.where(new firebase.firestore().FieldPath("category", "value"), '==', 'health')
我想知道我是否可以尝试在formik中获取category表单字段,只保存option.value而不是label和value

我看不出formik handleChange如何要求它只保存价值

即使这样,我也看不到如何查询firestore以使用数组的内容作为查询参数

有谁知道:

  • 如何通过formik表单提交到firestore,在自动完成中仅保存选项值(而不是选项标签和值)

  • 如何在firestore中查询数组的内容,以查看其属性之一是否与查询匹配

  • 这很奇怪,因为这表明可以使用我上面尝试过的表单对数组进行where查询。然而,这篇文章建议使用以下格式。collection(study/[docId])。其中(“value”、“==”、“health”)。我需要它来搜索集合中的每个文档,所以我不知道如何将这种方法应用于这个问题

    下面gso_gabriel的回答表明了两件令人困惑的事情。首先,假设我使用了一个子集合。我没有。添加下面的图片以显示类别字段在父文档中。我可以使用上面显示的格式在标题上执行where查询以提取值

    第二,也是最令人困惑的一点——它说:“因为你不能在数组中搜索对象”。这是什么意思?这是否表明无法对类别字段内的值内容执行查询?如果是这种情况,是否有资源为如何查询这段数据提供指导

    我也看到了——答案表明,使用firebase无法查询类别内的值。问题是我无法理解建议的替代方法。如果我正确理解了这篇文章,是否有任何教程可以扩展这些原则,以便我可以尝试找到不同的查询策略

    上的第一个答案还表明,不可能在类别内查询值。第二个答案建议在where查询中使用不同的格式,如下所示

    .where("category", "array-contains", {value: "health", label: "Health & Medical"})
    
    答案强调了将整个数组内容添加到大括号中的重要性。这很有效

    所以-这让我回到自动完成提交处理程序。这是一个多选字段,因此可能会选择多个值。如何在firebase文档中将这些值转换为一组单个值。即使只有一个,如何更改提交处理程序,使其只发送select选项值,而不发送值和标签


    如果无法查询数组中的对象-如何更改提交处理程序以仅向firebase添加选定选项值,而不是同时添加标签和值?第一个答案中建议的解决方法是添加一个字段,该字段仅包含要查询的值(so:health)。

    我将通过逐一回答您的问题来澄清您的疑问

    • 为了只保存
      ,您需要更改向Firestore发送信息的方式。更改
      变量,因为此变量同时维护
      标签
      中的值。总之,在与Firestore相关时,您需要基本上更改代码,在Firestore中,您可以使用
      标签
      值创建变量
    • 澄清你提到的这篇文章——通常NoSQL数据库是按照你将要查询的方式创建的。因此,您将首先根据需要对查询和数据库结构进行修改,这样您就不会遇到任何问题。由于无法在
      数组中搜索对象,因此我认为重构方案是最佳选择
    • 也许使用本例中阐明的子集合可以帮助您简化工作

    更改是您的最佳选择,因此您可以拥有一个完全适合您的查询和需求的方案-这是NoSQL的许多好部分之一,可以自由创建方案。

    在提交给firebase之前,您可以在
    onSubmit
    中更改发送的数据的形状

    onSubmit={(values, { setSubmitting }) => {
        setSubmitting(true);
    
        firestore.collection("study").doc().set({
         ...values,
         category: values.category.map(c => c.value),
         createdAt: firebase.firestore.FieldValue.serverTimestamp()
        })
        .then(() => {
            setSubmitionCompleted(true);
        });
    }}
    

    感谢您的注释@gso_gabirel。首先,关于自动完成的问题的原因是,如果我没有在表单元素中使用AllCategories数组,则选择菜单中显示的选项不会使用标签填充下拉列表。我找不到一个示例来说明如何只保存值,而不是同时保存标签和值。我在这个集合中没有子集合。我不知道你为什么认为我会。我有一个集合,其中包括一个名为category的属性。类别是一个数组。数组有一个名为“value”的属性,我正在尝试查询该属性。你的子集合常数
    .where(new firebase.firestore().FieldPath("category", "value"), '==', 'health')
    
    .where("category", "array-contains", {value: "health", label: "Health & Medical"})
    
    onSubmit={(values, { setSubmitting }) => {
        setSubmitting(true);
    
        firestore.collection("study").doc().set({
         ...values,
         category: values.category.map(c => c.value),
         createdAt: firebase.firestore.FieldValue.serverTimestamp()
        })
        .then(() => {
            setSubmitionCompleted(true);
        });
    }}