Search code examples
reactjsfirebasefirebase-storagefilepond

How To Fix Invalid argument in `put` at index 0: Expected Blob or File when using React, Firebase and Filepond


I'm trying to upload a users avatar when creting a firebase user, After creating a user here

auth.createUserWithEmailAndPassword(this.state.email,this.state.password)
    .then(credential=>{
     const photoUrl = this.handleUpload(credential)
})

I create a handle upload function which returns a photoUrl below

handleUpload=(credential)=>{
    const {avatar} = this.state;
    const upload = storage.ref(`avatars/${credential.user.uid}`).put(avatar)
    upload.on('state_changed',(snapshot)=>{
      let progress = (snapshot.bytesTransferred/snapshot.totalBytes)*100;
      console.log('Upload is ' + progress + '% done');
    },(e)=>{
      console.log(e)
    },()=>{
      return storage.ref("avatars").child(`${credential.user.uid}`).getDownloadURL()
    })
  }

and the filepond UI instance is declared in the UI as follows

const { ....,avatar,....} = this.state;

<FilePond 
  ref={ref => this.pond = ref}
  files={avatar}
  fileValidateTypeLabelExpectedTypes="Invalid File Type"
  imagePreviewMaxFileSize='3MB'
  imageValidateSizeMinWidth="400"
  imageValidateSizeMaxWidth="1024"            
  imageValidateSizeMinHeight="400"
  imageValidateSizeMaxHeight="1024"
  imagePreviewTransparencyIndicator="green"
  maxFileSize='3MB'
  labelIdle={'Drag & Drop your Profile Picture or <span class="filepond--label-action"> Browse </span>'}
  acceptedFileTypes={['image/png', 'image/jpeg']}
  onupdatefiles={fileItems => {
    this.setState({
      avatar: fileItems.map(fileItem => fileItem.file)
    });
  }}              
/>

But I get the expected blob or file error... How can I fix this?


Solution

  • It helps to log what the avatar value contains before it's sent to storage. Your storage is telling you it's not a Blob or a File.

    In this case it looks like avatar is an array.

    this.setState({
        avatar: fileItems.map(fileItem => fileItem.file) // this is an array
    });
    

    So instead of using avatar, which is the entire array, you can select the first element in the array with avatar[0]

    const upload = storage.ref(`avatars/${credential.user.uid}`).put(avatar[0])