0

I want to create a function that is about uploading photo to Firebase Storage with react-native-fetch-blob. I'm using Redux and you can find action functions below:

My problem is that uploadImage function is not running like asynchronous. Firebase function is running before uploadImage, so application give me an error.

I think i can't make a asynchronous function. How can i fix it ?

uploadImage() function:

const uploadImage = async (imageSource, whereToUpload) => {
  let imageURL = '';
  const mime = 'image/jpg';
  const { Blob } = RNFetchBlob.polyfill;
  const { fs } = RNFetchBlob;

  window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
  window.Blob = Blob;

  console.log('URI =>', imageSource.uri);

  let imgUri = imageSource.uri;
  let uploadBlob = null;
  const imageRef = firebase.storage().ref(whereToUpload + '/' + imageSource.fileName);
  const uploadUri = Platform.OS === 'ios' ? imgUri.replace('file://', '') : imgUri;
  await fs.readFile(uploadUri, 'base64')
  .then((data) => Blob.build(data, { type: `${mime};BASE64` }))
  .then((blob) => {
    uploadBlob = blob;
    return imageRef.put(blob, { contentType: mime });
  })
  .then(() => {
    uploadBlob.close();
    // eslint-disable-next-line no-return-assign
    return imageURL = imageRef.getDownloadURL();
  })
  .catch((error) => {
    console.log(error);
  });
  return imageURL;
};

and the main action is:

export const addProjectGroup = (
  myUser,
  groupName,
  groupDescription,
  groupProfilePic,
) => dispatch => {
  const groupProfileFinalPic = async () => {
    let finalGroupPicture = { landscape: '' };

    if (_.isEmpty(groupProfilePic.src)) {
      await uploadImage(groupProfilePic, 'groupPictures').then((imageURL) => {
      console.log('İŞLEM TAMAM!');
      console.log('SELECTED IMAGE URL =>', imageURL);
      finalGroupPicture.landscape = imageURL;
    });
    } else {
      finalGroupPicture.landscape = groupProfilePic.src.landscape;
    }
    return finalGroupPicture;
};

console.log("final group profile pic =>", groupProfileFinalPic());

  // Önce grubu yaratalım..
  // eslint-disable-next-line prefer-destructuring
  const key = firebase
    .database()
    .ref()
    .child('groups')
    .push().key;

  firebase
    .database()
    .ref('/groups/' + key)
    .set({
      admin: {
        email: myUser.email,
        name: myUser.name,
        uid: myUser.uid,
      },
      groupName,
      groupDescription,
      groupProfilePic: groupProfileFinalPic(),
      projects: '',
    })
    .then(() => {
      console.log('Groups oluşturuldu.');
    })
    .catch(e => {
      Alert.alert('Hata', 'Beklenmedik bir hata meydana geldi.');
      console.log(e.message);
    });

  dispatch({
    type: ADD_PROJECT_GROUP,
  });
};
0

2 Answers 2

1

You are not awaiting groupProfileFinalPic(). This should be done before creating the action you want to dispatch.

groupProfileFinalPic().then(groupProfilePic => {
    return firebase
        .database()
        .ref("/groups/" + key)
        .set({
            admin: {
                email: myUser.email,
                name: myUser.name,
                uid: myUser.uid
            },
            groupName,
            groupDescription,
            groupProfilePic,
            projects: ""
        })
        .then(() => {
            console.log("Groups oluşturuldu.");
        })
        .catch(e => {
            Alert.alert("Hata", "Beklenmedik bir hata meydana geldi.");
            console.log(e.message);
        });
});

I have no clue what the last dispatch is for, you might want to do that in one of the callbacks. Your code is to verbose for an SO question, but I hope this helps anyways.

Sign up to request clarification or add additional context in comments.

1 Comment

Can you explain with fixing code please ? Thank you so much.
0

You are using both await and then on the same call. To use await, you can arrange it something like

const uploadImage = async (imageSource, whereToUpload) => {
    ...
    try {
        let data = await RNFS.fs.readFile(uploadUri, 'base64')
        let uploadBlob = await Blob.build(data, { type: `${mime};BASE64` }))
        ...etc...
        return finalResult
    catch (e) {
        // handle error
    }


}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.