Function CollectionReference.add() requires its first argument to be of type object, but it was: undefined

Viewed 7487

I want to store the image in firebase storage and pass its URL reference in firestore. So I'm able to upload an image in storage but unable to pass the image URL reference in cloud firestore.

import React , {Component} from 'react';
import fire from './../fire'
import Uploadimg from './Uploadimg'

class Adproduct extends Component{

  geturl = (imurl) =>{
      this.setState({
          img:imurl
        });
  }
  submit = e =>{
      e.preventDefault()
      var db= fire.firestore();

      db.settings({
        timestampsInSnapshots: true
           });

      db.collection('newproducts').add(this.State)
      .then(res =>{
          console.log(res.id)

          this.props.submit()
      })
      .catch(err =>{
          console.log('something went wrong',err)
      })
  }
  takedata = e =>{
      this.setState({
          [e.target.name]: e.target.value 
      });
  }

  constructor(props){
      super(props);
      this.state ={
          name:'',
          productdetails:'',
          size:'',

      }
  }

  render() {

      return (
          <div className="container w3-padding">

          <div className="row w3-padding">
          <div className="col-md-6 w3-padding">
                   <h3 className="w3-tag w3-padding w3-center">Add New</h3>
              <form className="w3-container" onSubmit={this.submit}>

                     <label className="w3-text-blue"><b>Name</b></label>
                <input className="w3-input w3-border" type="text" name="name" value={this.state.name} onChange={this.takedata} required/>

                <label className="w3-text-blue"><b>productdetails</b></label>
                <input className="w3-input w3-border" type="text" name="productdetails" value={this.state.productdetails} onChange={this.takedata} required/>

            <label className="w3-text-blue"><b>size available</b></label>
            <input className="w3-input w3-border" type="text" name="size" value={this.state.size} onChange={this.takedata} required/>


                   <br/>
                   <Uploadimg geturl={this.geturl} />
                   <br/>
                    <button className="w3-btn w3-blue">Add</button>

                 </form>
          </div>
          </div>
          </div>
      );
  }

}
export default Adproduct;
7 Answers

If the accepted answer doesn't help you, you might be having the same issue I was having.

I solved this by using the typescript spread operator:

add(wizard: Wizard): Promise<DocumentReference> {
return this.wizardCollection.add({...wizard});

}

Hope this helps you.

it can happen if you forgot to create database in the project... Its happen to me - I copy the project secret key - but forgot to actually create database in the project.... after I create the DB - it solved...

use

db.collection('newproducts').add({...this.State})

instead of

db.collection('newproducts').add(this.State)

It simply works for me.

Go in Database -> Rules ->

Change allow read, write: if false; to true;

It can happen because either you have not created any database or have no permission to read/write on the database from Under Rules tab i.e,

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

You should create the Firestore database, allow the read, write rules, and configure it to your project. Then you can use the spread operator as below to save.

saveStudent(student: Student) {
    return new Promise<Student> ((resolve, reject) => {
      this.fireStore.collection('students').add({...student}).then(res => {}, err => reject(err));
    });
  }

From the documentation

To use a custom class, you must define a FirestoreDataConverter function for your class. For example:

class City {
    constructor (name, state, country ) {
        this.name = name;
        this.state = state;
        this.country = country;
    }
    toString() {
        return this.name + ', ' + this.state + ', ' + this.country;
    }
}

// Firestore data converter
var cityConverter = {
    toFirestore: function(city) {
        return {
            name: city.name,
            state: city.state,
            country: city.country
            }
    },
    fromFirestore: function(snapshot, options){
        const data = snapshot.data(options);
        return new City(data.name, data.state, data.country)
    }
}

Call your data converter with your write operation:

// Set with cityConverter
db.collection("cities").doc("LA")
  .withConverter(cityConverter)
  .set(new City("Los Angeles", "CA", "USA"));
Related