Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.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
Javascript React/Firebase->;使用无效数据调用DocumentReference.set()。不支持的字段值:未定义_Javascript_Reactjs_Firebase_Google Cloud Firestore - Fatal编程技术网

Javascript React/Firebase->;使用无效数据调用DocumentReference.set()。不支持的字段值:未定义

Javascript React/Firebase->;使用无效数据调用DocumentReference.set()。不支持的字段值:未定义,javascript,reactjs,firebase,google-cloud-firestore,Javascript,Reactjs,Firebase,Google Cloud Firestore,我试图在Firebase的后端添加一个集合中的文档,由于函数firestoreAutoId(),该集合的名称是随机生成的。但是,当我提交表单时,React返回一个错误,上面写着“创建用户FirebaseError时出错:函数DocumentReference.set()使用无效数据调用。不支持的字段值:未定义(在文档AVU/[object]中的字段lastname中找到) “,这可能看起来很愚蠢,但我真的不明白为什么会出现此错误。无论我是否更改名称或值,这都会导致另一个问题。” 以下是完整的代码

我试图在Firebase的后端添加一个集合中的文档,由于函数
firestoreAutoId()
,该集合的名称是随机生成的。但是,当我提交表单时,React返回一个错误,上面写着“创建用户FirebaseError时出错:函数DocumentReference.set()使用无效数据调用。不支持的字段值:未定义(在文档AVU/[object]中的字段lastname中找到) “,这可能看起来很愚蠢,但我真的不明白为什么会出现此错误。无论我是否更改名称或值,这都会导致另一个问题。”

以下是完整的代码,以便更好地理解:

AddDelivery.Js

import { createDelivery, firestoreAutoId } from '../firebase';
import './AddDelivery.css';

class AddDelivery extends Component {
    state = {when: '', whath: '', from: 0, to: 0, to_adress: '', to_tel: 0, name: '', to_name: '', name2: '', tel: 0, adress: '', info_comp: '', taken: false, taken_by: "X", city:''};
    handleChange = (e) => {
        const { name, value } = e.target;

        this.setState({ [name]: value });
    };
    handleSubmit = async (e) => {
        e.preventDefault();
        const {when, whath, from, to, to_adress, to_tel, name, to_name, name2, tel, adress, info_comp, taken, taken_by, city} = this.state;
        try {
            let id
            id = firestoreAutoId()
            await createDelivery({ id }, { when }, { whath }, { from }, { to }, { to_adress }, { to_tel } , { name } , { to_name }, { name2 }, { tel } , { adress } ,  { info_comp } , { taken } , { taken_by } , { city });
        } catch (error) {
            console.log('error', error);
        }
        this.setState({id: '', when: '', whath: '', from: 0, to: 0, to_adress: '', to_tel: 0, name: '', to_name: '', name2: '', tel: 0, adress: '', info_comp: '', taken: false, taken_by: "X", city:''});
    };
    render() {
    const {when, whath, from, to, to_adress, to_tel, name, to_name, name2, tel, adress, info_comp, taken, taken_by, city} = this.state;
    return (
        <div className="main-wrapper">
            <div className="form-main-wrapper">
                <p className="form-add-delivery-hero-title">Ajouter une livraison</p>
                <form className="form-wrapper" onSubmit={this.handleSubmit}>
                    <div className="form-when-wrapper">
                        <div className="form-when">
                            <label>Quand ?</label>
                            <input type="date" name="when" value={when} onChange={this.handleChange} required></input>
                        </div>
                        <div className="form-when-hour">
                            <label>A quelle heure ?</label>
                            <input type="time" name="whath" value={whath} onChange={this.handleChange} required></input>
                        </div>
                        <div className="form-city-name">
                            <label>Ville ?</label>
                            <select className="form-city-selector" name="city" value={city} onChange={this.handleChange}>
                                <option value="Lyon">Lyon</option>
                                <option value="Montpellier">Montreuil</option>
                                <option value="Paris">Paris</option>
                                <option value="Vélizy-Villacoublay">Vélizy-Villacoublay</option>
                                <option value="Viroflay">Viroflay</option>
                            </select>
                        </div>
                    </div>
                    .... Same for the rest of the form..
谢谢你的帮助!

臭虫 1.重置组件的状态 您最初将状态设置为:

state = {when: '', whath: '', from: 0, to: 0, to_adress: '', to_tel: 0, name: '', to_name: '', name2: '', tel: 0, adress: '', info_comp: '', taken: false, taken_by: "X", city:''};
但这与创建传递后设置的状态不匹配:

this.setState({id: '', when: '', whath: '', from: 0, to: 0, to_adress: '', to_tel: 0, name: '', to_name: '', name2: '', tel: 0, adress: '', info_comp: '', taken: false, taken_by: "X", city:''});
您应该将默认状态存储为对象,然后使用该状态重置组件:

const DEFAULT_STATE = {when: '', whath: '', from: 0, to: 0, to_adress: '', to_tel: 0, name: '', to_name: '', name2: '', tel: 0, adress: '', info_comp: '', taken: false, taken_by: "X", city:''};
/* ... */
state = { ...DEFAULT_STATE }; // take a shallow copy of DEFAULT_STATE
/* ... */
this.setState({ ...DEFAULT_STATE }); // use a shallow copy of DEFAULT_STATE
2.文件ID 此行错误地将引用设置为
av\u deliveries/[object object]

firestore.doc(`av_deliveries/${id1}`); // id1 is an object of shape { id: string }
3.
createDelivery()的参数不正确
调用
createDelivery()
时,第九个参数是用
{to_name:string}
调用的,但您需要的是
{lastname:string}

下一行将始终将
lastname
设置为
undefined

const { lastname } = { to_name: 'any string' };
4.解构模式的错误使用 解构模式的目的是将变量放入单个对象中,然后提取所需的属性。它还用于避免为函数提供大量参数

这一行:

await createDelivery({ id }, { when }, { whath }, { from }, { to }, { to_adress }, { to_tel } , { name } , { to_name }, { name2 }, { tel } , { adress } ,  { info_comp } , { taken } , { taken_by } , { city });
应该是:

await createDelivery({ id, when, whath, from, to, to_adress, to_tel, name, to_name, name2, tel, adress, info_comp, taken, taken_by, city });
export const createDelivery = async ({ id, when, whath, from, to, to_adress, to_tel, name, to_name, name2, tel, adress, info_comp, taken, taken_by, city }) => {
  /* ... each property in the above object is available as a variable ... */
}
或者,如果名称匹配,您可以使用以下任一选项:

await createDelivery(this.state);
// or
await createDelivery({ ...this.state });
这些线路:

export const createDelivery = async (id1, when1, whath1, from1, to1, adress_to1, tel_to1, name1, name2, tel1, adress1, info_comp1, taken1, taken_by1, city1) => {
  /* ... */

  const { id } = id1;
  const { when } = when1;
  const { whath } = whath1;
  const { from } = from1;
  const { to } = to1;
  const { adress_to } = adress_to1;
  const { tel_to } = tel_to1;
  const { name } = name1;
  const { lastname } = name2;
  const { tel } = tel1;
  const { adress } = adress1;
  const { info_comp } = info_comp1;
  const { taken } = taken1;
  const { taken_by } = taken_by1;
  const { city } = city1;

  /* ... */
}
应该是:

await createDelivery({ id, when, whath, from, to, to_adress, to_tel, name, to_name, name2, tel, adress, info_comp, taken, taken_by, city });
export const createDelivery = async ({ id, when, whath, from, to, to_adress, to_tel, name, to_name, name2, tel, adress, info_comp, taken, taken_by, city }) => {
  /* ... each property in the above object is available as a variable ... */
}
5.无需
firestoreAutoId()
这些行执行相同的操作(除非
firestoreAutoId()
正在执行意外操作):

6.几乎不需要检查是否存在新的自动id文档 在当前代码中,使用生成的ID创建一个新文档引用,从数据库中读取它,然后仅在数据不存在时写入它

生成的ID大约有,1%的冲突几率,你必须生成大约163万亿个ID。因为这不太可能,Firestore限制每秒写入10k个,按照这个速度,你必须花费大约517000年的时间来最大化这个上限才能获得这么多的ID

因此,可以删除这些行:

const snapshot = await userRef.get();
if (!snapshot.exists) { /* ... */ }
如果你确实不想发生冲突,那就把它挡在你的电脑里,而不是依赖客户

应用更改
数组确实存在问题,变量的名称很难解释,很抱歉,但是当我尝试在数据库的字段id中传递id时,会显示一个错误
添加传递时出错FirebaseError:Function DocumentReference.set(),调用的数据无效。不支持的字段值:未定义(可在文件av_deliveries/wcuJS9gDJXaEPmmVrWrC中的字段id中找到)
否则,如果没有id,它可以完美地工作,谢谢!@tomdebout用更多错误和建议扩展了答案
const snapshot = await userRef.get();
if (!snapshot.exists) { /* ... */ }
// AddDelivery.js
import { createDelivery } from '../firebase';
import './AddDelivery.css';

const DEFAULT_STATE = {when: '', whath: '', from: 0, to: 0, to_adress: '', to_tel: 0, name: '', to_name: '', name2: '', tel: 0, adress: '', info_comp: '', taken: false, taken_by: "X", city: ''};

class AddDelivery extends Component {
  state = { ...DEFAULT_STATE };
  
  handleChange = (e) => {
    const { name, value } = e.target;

    this.setState({ [name]: value });
  };
  
  handleSubmit = async (e) => {
    e.preventDefault();
    try {
      await createDelivery(this.state);
    } catch (error) {
      // never called unless you have a syntax error?
      console.log('error', error);
    }
    this.setState({ ...DEFAULT_DATA });
  };
  
  render() {
    const {when, whath, from, to, to_adress, to_tel, name, to_name, name2, tel, adress, info_comp, taken, taken_by, city} = this.state;
    
    /* ... */
  }
}
// firebase.js
export const createDelivery = async ({ when, whath, from, to, to_adress, to_tel, name, to_name, name2, tel, adress, info_comp, taken, taken_by, city }) => {
  // create a new document in the "av_deliveries" collection.
  const userRef = firestore.collection("av_deliveries").doc();
  
  // to_name, taken and taken_by are unused?
  const data = {
    id: userRef.id,
    when,
    whath,
    from,
    to,
    adress_to: to_adress, // consider naming these the same
    tel_to: to_tel, // consider naming these the same
    name,
    lastname: name2, // consider naming these the same
    tel,
    adress,
    info_comp,
    city,
  };

  try {
    await userRef.set(data);
    return data; // return data when successful
  } catch (error) {
    console.log('Error in creating user', error);
    return false; // return false on failure
  }
};