nuxt-community / firebase-module

🔥 Easily integrate Firebase into your Nuxt project. 🔥
https://firebase.nuxtjs.org
MIT License
641 stars 99 forks source link

Firebase storage upload not working when clearing all site data (or new user of the app) #494

Closed kostadin-t closed 2 years ago

kostadin-t commented 3 years ago

This is a problem i have been trying to solve for the last couple of weeks with no success. My store action is working fine and images are uploaded successfully when the website stores some data, meaning if you are not a new user and you haven't cleared site data from chrome>settings>site settings. However if you do that the same code doesn't work and only one image or sometimes not even one is uploaded. The worst part is that no error is thrown, neither by the firebase upload task, nor by the catch block.

This is the code i use. I know it is very ugly but after everything i tried i just want to find the problem and then refactor. Please help.


createAd ({ commit }, ad) {
    this.$fire.database.ref('ads').push(ad).then(data => data.key)
      .then(async (key) => {
        console.log('adding new ad with unique key:', key);
        const images = []
        this.$fire.database.ref('ads').child(key).update({ id: key })

        const storageRef = this.$fire.storage.ref();
        const imageRef = storageRef.child(`ad_images/${key}${ad.mainImage.name}`);
        // This is not resolved if you clear site data
        const mainImageUpload = imageRef.put(ad.mainImage);
        mainImageUpload.on('state_changed',
          (snapshot) => {
            const uploadPercentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            console.error('upload progress in %:', uploadPercentage);
          },
          error => console.error(error),
          () => {
            console.error('main image upload succesful');
            mainImageUpload.snapshot.ref.getDownloadURL().then((downloadURL) => {
              console.error('main image uploaded at:', downloadURL);
              mainImageUpload.snapshot.ref.getMetadata().then(({ name }) => {
                ad.mainImageUrl = { data: downloadURL, name };
                console.log('adding main image url for ad', ad.mainImageUrl);
                this.$fire.database.ref('ads').child(key).update({ mainImageUrl: { data: downloadURL, name } })

                if (!ad.images.length) {
                  commit('createAd', { id: key, ...ad })
                }
              });
            });
          }
        );

        const uploadImage = (image, i) => {
          return new Promise((resolve) => {
            const storageReference = this.$fire.storage.ref();
            const imageReference = storageReference.child(`ad_images/${key}${image.name}`);
            const imageUpload = imageReference.put(image);
            imageUpload.on('state_changed',
              (snapshot) => {
                const uploadPercentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
                console.error('image upload progress in %:', uploadPercentage);
              },
              error => console.error(error),
              () => {
                console.log('successful image upload');
                imageUpload.snapshot.ref.getDownloadURL().then((downloadURL) => {
                  console.error('image uploaded at:', downloadURL);
                  imageUpload.snapshot.ref.getMetadata().then(({ name }) => {
                    console.log('adding images for ad', name, downloadURL)

                    images.push({ data: downloadURL, name })

                    if (i === ad.images.length - 1) {
                      this.$fire.database.ref('ads').child(key).update({ imageUrls: images })

                      ad.imageUrls = images;
                      commit('createAd', { id: key, ...ad });
                    }

                    return resolve();
                  });
                });
              });
          })
        }

        if (ad.images.length) {
          for (let i = 0; i < ad.images.length; i++) {
            const image = ad.images[i];
            await uploadImage(image, i);
          }
        }
      }).catch(error => console.error('creating ad error', error));`
kostadin-t commented 3 years ago

Anyone with the same problem?

lupas commented 3 years ago

Hey @kostadin-t

Sorry for the late response - Is this still an issue?

kostadin-t commented 3 years ago

Hey @kostadin-t

Sorry for the late response - Is this still an issue?

Yes. It still the same.

lupas commented 3 years ago

Hey @kendalled I think your problem might be that you are mixing state_changed listeners with for loops... Also, you are using await in a regular for loop, which doesn't wait for completion, maybe it will work if you change your for loop to something like this:

const promises = []

for (let i = 0; i < ad.images.length; i++) {
  const image = ad.images[i]
  promises.push(uploadImage(image, i))
}

const responses = await Promise.all(promises)

Your example is quite cumbersome to debug and contains a lot of unneeded code for us to debug. Could you provide a minimal working example where this issue happens and maybe upload it to codesandbox?

For the future: This is a question not really specific to the Nuxt/Firebase module and rather a general Firebase Storage question, so you would be better advised to ask it on StackOverflow.

lupas commented 2 years ago

Closing due to inactivity.