react-native warning: Possible unhandled promise: can't find variable: listeners

2.2k Views Asked by At

I am getting this warning when I run my react-native mobile app. I try to upload photo with react-native-image-picker to firebase (in the storage) and save the url of this photo in the firebase (database). The upload is made succefully but when the program try to save the url in database the app give a warning: "Possible Unhandled Promise Rejection: Can't find variable: listeners". Below is my code:

ImagePicker.showImagePicker(options, (response) => {

  let filePath = response.path;
  let fileName = this.props.imageName;
  let rnfbURI = RNFetchBlob.wrap(filePath);
  Blob
     .build(rnfbURI, { type : 'image/png;'})
     .then((blob) => {
  // upload image using Firebase SDK
        this.props.bdd.storage()
            .ref('images')
            .child(fileName)
            .put(blob, { contentType : 'image/jpg' })
            .then((snapshot) => {

                 console.log('Uploaded', snapshot.totalBytes, 'bytes.');
                 console.log(snapshot.metadata);
                 console.log('downlo='+snapshot.metadata.downloadURLs[0]);
                var ref = this.props.bdd.database().ref('promotions/'+ fileName);
                alert(snapshot.metadata.downloadURLs[0]);
                ref.update({
                  image_url:snapshot.metadata.downloadURLs[0]
                });
               }).catch(function(error) {
                console.error('Upload failed:', error);
                 });
     })   

});

}

2

There are 2 best solutions below

0
On

I think it is caused because you are not making a complete promise, usually it looks like this:

yourPromise()
.then((response) => {/*this callback will be executed if promise is completed*/}, 
      (cause) => {/*this callback will be executed if promise is rejected*/})
.catch((err) => {/*this callback will be execute if some exception is thown*/});
0
On

You indeed don't handle outer promise (Blob.build one) rejection. The problem is that if this operation fails, throws, etc. then you will not be able to recover, because you simply don't handle this case.

Correct approach would be to return inner promise with return this.props.bdd.storage() and add catch block to the outer block. Something like this:

Blob
  .build(rnfbURI, {
    type: 'image/png;'
  })
  .then((blob) => {
    // upload image using Firebase SDK
    return this.props.bdd.storage()
      .ref('images')
      .child(fileName)
      .put(blob, {
        contentType: 'image/jpg'
      })
      .then((snapshot) => {

        console.log('Uploaded', snapshot.totalBytes, 'bytes.');
        console.log(snapshot.metadata);
        console.log('downlo=' + snapshot.metadata.downloadURLs[0]);
        var ref = this.props.bdd.database().ref('promotions/' + fileName);
        alert(snapshot.metadata.downloadURLs[0]);
        ref.update({
          image_url: snapshot.metadata.downloadURLs[0]
        });
      })
      .catch(function(error) {
        console.error('Upload failed:', error);
        throw error;
      });
  })
  .catch(error => {
    console.log('One of the above operations failed', error)
  })

Note this part:

.catch(function(error) {
  console.error('Upload failed:', error);
  throw error;
})

If this.props.bdd.storage() fails you will get into this error handler and then by re-throw'ing error you make it propagate further out to the outer catch block. So all possible rejections are handled.