Firebase Storage Task (Progress bar)

Viewed 726

I am trying to do a content upload progress bar using Firebase storage, but I am having some problems returning the task from my function.

I have implemented a Firebase Singleton, using React Context API. In the Firebase component I have multiples functions, one of them called 'uploadContent'

Here is the code:

  uploadContent = async (postInfo) => {
    const { uri, description, location, tags } = postInfo;

    // Post UUID
    const postId = uuid();

    // Upload to firestore
    const data = {
      id: postId,
      description,
      location,
      tags,
      time: firestore.Timestamp.fromDate(new Date()), // The time when the image is uploaded
      likes: [], // At the first time, when a post is created, zero users has liked it
      comments: [], // Also, there aren't any comments
    };

    await this.db
      .collection("posts")
      .doc(this.auth.currentUser.uid)
      .collection("userPosts")
      .add(data);

    // Create a storage referece
    const storageRef = firebase.storage().ref("photos").child(postId);

    // Uri to Blob
    const response = await fetch(uri);
    const blob = await response.blob();

    // Upload to storage
    const task = storageRef.put(blob);

    return task;
  };

The thing is, that when I call this function from my uploader component, and try to use one of the returned object functions I get "[Unhandled promise rejection: TypeError: undefined is not a function (near '...task.on...')]", and I don't know how to solve this problem.

Pd: If I call this function inside the "uploadContent" method (where I create the task), it works fine, but I need to return the task...

Here is the code of the function where I call my firebase method:

  const upload = async () => {
    const { firebase, navigation } = props;

    console.log("Uploading...");

    // Prepare post information
    const postInfo = {
      uri: photo.uri,
      description: descriptionInput.current.props.value,
      location: locationName, // TODO - Object with the location coords too
      tags: [], // TODO - users tagged
    };

    // Upload to firebase
    const task = await firebase.uploadContent(postInfo);

    task.on("state_changed", (taskSnapshot) => {
      console.log(
        `${taskSnapshot.bytesTransferred} transferred out of ${taskSnapshot.totalBytes}`
      );
    });

    // navigation.navigate("Profile"); // TODO: route params -> task
  };

Any ideas? Thanks.

1 Answers

I wasted so much time on a similar problem, but solved it! In this part of the code, you are resolving the task (that is implemented with promise) into the value undefined.

// Upload to firebase
const task = await firebase.uploadContent(postInfo);

Just remove the await to use the task itself.

Related