"Every time you use Firebase storage, you can expect a

I am facing an issue with my Vue 3 application. I am trying to retrieve a link to a document from the repository, but all I keep getting is a promise instead of the actual link. Can someone help me understand why this is happening?

async FetchData({ state, commit }, to) {
  try {
    commit("setLoading", true);
    const q = query(collection(db, to));

    await onSnapshot(q, (querySnapshot) => {
      const data = [];

      querySnapshot.forEach((doc) => {
        let films = async (to) => {
          const starsRef = ref(storage, `images/${doc.id}/poster.png`);

          return await getDownloadURL(starsRef);
        };

        // const poster=`gs://cell-11ef4.appspot.com/images/${doc.id}/poster.png`

        let item = {
          id: doc.id,
          name: doc.data().name,
          slug: doc.data().slug,
          country: doc.data().country,
          duration: doc.data().duration,
          year: doc.data().year,
          video: doc.data().video,
          genres: doc.data().genres,
          actors: doc.data().actors,
          poster: to === "films" ? films() : null,
          // BipPoster: url,
        };

        data.push(item);

        // Get the download URL
      });

      commit("setData", { data, to });
    });
  } catch (err) {
    console.log(err);
  } finally {
    commit("setLoading", false);
  }
}
let url = async () => {
  let url;
  const starsRef = ref(storage, `images/${doc.id}/poster.png`);

  await getDownloadURL(starsRef).then((p) => {
    url = p;
  });

  return url;
};

The Output I am currently getting:

https://i.sstatic.net/FXYdI.png

https://i.sstatic.net/Etf0O.png https://i.sstatic.net/zrjn8.png

Answer №1

To efficiently handle multiple promises in JavaScript, it is recommended to utilize Promise.all() method like so:

const promises = [];
querySnapshot.forEach((doc) => {
     const starsRef = ref(storage, `images/${doc.id}/poster.png`);

     promises.push(getDownloadURL(starsRef));
});

const urlsArray = await Promise.all(promises);

Answer №2

Convert the documents collection into an array of promises that will resolve with complete item data, including download URL, and await all of them using Promise.all().

You are also setting up a real-time updates listener, which contradicts what you intend for FetchData to accomplish. It is recommended to use getDocs() instead of onSnapshot()

async FetchData({ state, commit }, to) {
  try {
    commit("setLoading", true);

    // `onSnapshot` registers a real-time updates listener,
    // use `getDocs` to retrieve documents
    const { docs } = await getDocs(query(collection(db, to)));

    // Iterate through the `docs` array and return fully detailed objects
    const data = await Promise.all(
      docs.map(async (doc) => ({
        ...doc.data(),
        id: doc.id,
        poster:
          to === "films"
            ? await getDownloadURL(ref(storage, `images/${doc.id}/poster.png`))
            : null,
      }))
    );

    commit("setData", { data, to });
  } catch (err) {
    console.error(err);
  } finally {
    commit("setLoading", false);
  }
},

If you truly want to set up a real-time updates listener, do it in an effect hook where you can also clean up the listener

useEffect(() => {
  // Return the unsubscribe function as cleanup
  return onSnapshot(query(collection(db, to)), async ({ docs }) => {
    try {
      const data = await Promise.all(
        docs.map(async (doc) => ({
          ...doc.data(),
          id: doc.id,
          poster:
            to === "films"
              ? await getDownloadURL(
                  ref(storage, `images/${doc.id}/poster.png`)
                )
              : null,
        }))
      );

      commit("setData", { data, to });
    } catch (err) {
      console.error(err);
    }
  });
}, [to]);

Answer №3

async FetchData({ state, commit }, destination) {
  try {
    const queryData = query(collection(db, destination));

    await onSnapshot(queryData, (querySnapshot) => {
      const allItems = querySnapshot.docs.map(async (doc) => {
        let item = {
          id: doc.id,
          name: doc.data().name,
          slug: doc.data().slug,
          country: doc.data().country,
          duration: doc.data().duration,
          year: doc.data().year,
          video: doc.data().video,
          genres: doc.data().genres,
          actors: doc.data().actors
        };
        if (destination === "films") {
          const starsRef = ref(storage, `images/${doc.id}/poster.png`);
          item.poster = await getDownloadURL(starsRef);
        }
        return item;
      });
      Promise.all(allItems)
        .then((data) => commit("setData", { data, destination }))
        .catch(console.error);
    });
  } catch (error) {
    console.error(error);
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Concealing the Load More Data Button in ASP.net MVC using Ajax and Javascript

I'm trying to implement a feature in my asp.net mvc5 web application where more records are loaded via ajax when a button is clicked. However, as a newcomer to javascript, I'm struggling to hide the "load more" button when the current page number ...

Is it possible to operate a jQuery mobile web application while disconnected?

Recently, I've been experimenting with the idea of creating a web application using jQuery Mobile that involves utilizing forms such as checkboxes, text fields, and combo boxes. The tasks associated with this app are quite simple, but they require dat ...

How can PHP be used to access every element within an array that has been passed through an AJAX call?

I am having trouble accessing elements within an array from my PHP file after passing the array through an ajax call. Here is the code for the ajax call: var data = ['test1', 'test2', 'test3']; $(document).ready(function () { ...

What method is most effective for storing 'likes' in Firebase?

In my Firebase database, the structure is set up as follows: users: [ {userId: {...}}, // Contains private data for each user ... ], likes: [ // Publicly accessible goodsId: [111, 222, 333, 444] // Users' ids ] Goods categories and item ...

After an error occurs, the Node.js Restify code will be executed

Within a Restify route, I have set up a router handler that calls a custom module for error checking. If the code encounters an error condition, it returns next(err) and displays the error message in the browser. However, the code does not stop executing a ...

Using Laravel with Vue and <router-link> does not update the content as expected

For my project, I am using Laravel with Vue. On the main page, I have listed all articles and when a user clicks on a specific article, a new page opens displaying that article with other prominent articles shown on the side like this: .https://i.stack.img ...

How to send route parameters to a controller function in ExpressJS

I'm currently working on setting up user authentication for my application using passport JS. I am facing a challenge in passing the passport variable between app.js, routes.js, and controller.js. Despite trying various approaches, I have been unsucce ...

Ways to stop user authentication in Firebase/Vue.js PRIOR to email verification

I am currently working on a Vue.js and Firebase authentication interface with an email verification feature. The setup is such that the user cannot log in until they click the verification link sent to the email address provided during the login process. ...

Automated browsing: identifying the difference between AJAX and iframes

During my automated requests (scheduled at specific times, without user involvement), I have noticed that xmlHttpRequest includes extra http headers. In order for the server not to be able to distinguish these requests as automated (they should appear exa ...

Exploring the process of iterating through and organizing a JavaScript array

Recently, I encountered a JavaScript object that was generated by a particular API. The object is structured in a way that it can potentially have multiple instances of the same 'equity' (such as Hitachi Home in this case): { "results": { ...

Ways to combine multiple then() promises into a single one

I have a section of code where I am using multiple then() methods. I am looking to streamline this and have it only utilize one then(). Is there a way to achieve this? getGreeting = () => { fetch(url) .then((response) => response.json()) ...

Why is fading out columns in an HTML table with jQuery's .fadeTo() method taking so long?

I am looking to implement a functionality where all cells in a column of my HTML table fade out when I click on a button located in the header of that column. I have written the following JavaScript code to achieve this: ... myDOMElement.find(".headerIcon ...

Using jQuery and AJAX manipulates the value of my variable

My AJAX request seems to be causing jQuery to change the variable that is passed to it. Here is the JavaScript code: <script type="text/javascript"> function ResolveName(id) { $.ajax({ url : 'resolvename.php', ...

What is the best way to transform an array of objects into a single string in JavaScript?

After receiving the input from req.body, it looks like this: [ { "Name": "Test_1", "Level 1": "Story_1", "Level 2": "Story_1.1" }, { "Name": & ...

Significant lag experienced when using $rootscope.$on with a large object

In my AngularJS project, I am working with a JavaScript object (factory) that contains numerous functions spanning 4000 lines. Creating the object from data fetched from PHP happens pretty quickly. $http.get('pivots/list.php') .succe ...

Add a JavaScript library to the header directly from the body of a webpage, ensuring it is exclusive to a single

I am using the Google Charts JS library on a single page within my project, with external and global headers and footers. The head tags are located in a head.php file, where all required JS libraries are included. The structure of my pages is as follows: ...

javascript implementing optional chaining for a single parameter

Is it possible to implement optional chaining on a single parameter? setAllProperties( Object.values(users).flatMap(({ properties }) => Object.values(properties) ) ); I am looking for a way to ensure that the properties folder exists in ...

JSP Implementation of a Gravity-Driven Dynamic List

I am looking for a way to automatically populate a dropdown list within a JSP page form using values retrieved from a database query. The challenge is that only a limited number of rows are being pulled from the database based on other form inputs. I am no ...

Angular directive failed to correctly retrieve object

I have a person object loaded from the backend that is structured as follows: { "PersonId":"19894711-2eb9-4edf-92c6-85de2b33d1bb", "Firstname":"Jacky", "Lastname":"Chan", "DateOfBirth":"1963-09-18T00:00:00", "CreateDate":"2015-12-11T09 ...

Unlimited Possibilities in Designing Shared React Components

Seeking the most effective strategies for empowering developers to customize elements within my React shared component. For example, I have a dropdown and want developers to choose from predefined themes that allow them to define highlight color, font siz ...