oh3vci
oh3vci

Reputation: 72

How to return value after all promise in React and Firebase?

I'm making web site using react based on Firebase. Recently, I met some problem about getting url of storage. Below is my codes.

(state, action) => {
  const snapshot = action.payload;
  const list = [];

  snapshot.forEach((child) => {
    list.push({
      key: child.key,
      user_bg_url: child.val().user_bg_url,
      user_hp: child.val().user_hp,
      user_id: child.val().user_id,
      user_img_url: child.val().user_img_url,
      user_login_yn: child.val().user_login_yn,
      user_msg_block: child.val().user_msg_block,
      user_token: child.val().user_token,
    });
  });

  list.forEach(async (user) => {
    await storage.getUserImage(user.user_img_url).then((url) => {
      user.user_img_url = url;
    });
  })

  return state.setIn(['users', 'list'], list);
}

getUserImage: (gs_url) => {
  return storage.refFromURL(gs_url).getDownloadURL();
},

I want to return value after work of 'list.forEach'. But it just return blank array before completion of 'list.forEach'.

Upvotes: 1

Views: 544

Answers (1)

Jeff
Jeff

Reputation: 2490

You're correct that return is getting called before your forEach completes, so you'll need to return a promise. Using Promise.all() and map would work here.

return Promise.all(list.map(async (user) => {
  await storage.getUserImage(user.user_img_url).then((url) => {
    user.user_img_url = url;
  });
})).then(() => {
  return state.setIn(['users', 'list'], list);
});

Inspired by this answer.

Upvotes: 2

Related Questions