尝试使用Promises和.then()从Firebase获取Image-Url

时间:2018-07-20 17:11:46

标签: javascript firebase react-native es6-promise

我正试图获取一些团体及其信息。 我需要加入firebase才能在每次群聊中获取最新消息。我已经开始工作了。 现在,我还必须从Firebase存储中获取Group-Image Url。我正在尝试使用Promise和.then()在Promise解决后继续进行。

我的想法是,对于每个组,它将使用带有groupId的getGroupImages()函数来获取图像。一旦有了图像,就会触发.then()中的代码。

这是我的代码以及我要执行的操作:

export const getUserGroups = () => {
  return (dispatch) => {
    dispatch({ type: GET_USERS_GROUPS });
    const uid = firebase.auth().currentUser.uid;
    firebase.database().ref(`/userGroups/${uid}/`)
      .on('value', snapshot => {
        const promises = [];
        snapshot.forEach(child => {
          const children = child.val();
          const groupId = children.groupId;
          getGroupImages(groupId).then((image) => {
            children.image = image;
            const promise = firebase
              .database()
              .ref(`/groups/${groupId}/lastmessage`)
              .once('value')
              .then(snap => {
                children.lastmessage = snap.val();
                return children;
              });
              promises.unshift(promise);
          })
          .catch((e) => console.log(e));
        });
        Promise.all(promises)
        .then(groupArr => {
          dispatch({ type: GET_USERS_GROUPS_SUCCESS, payload: groupArr });
        })
        .catch((e) => console.log(e));
      });
  };
};

这是我写的getGroupImages()函数:

const getGroupImages = (groupId) => {
  return new Promise(() => (resolve, reject) => {
    const ref = firebase.storage().ref(`images/${groupId}/groupImg`);
    ref.getDownloadURL()
      .then((image) => {
        resolve(image);
      })
      .catch((e) => reject(e));
  })
  .catch((err) => console.log(err));
};

我对使用诺言很陌生,我正在尝试学习诺言,但在这里我真的不知道自己在做错什么。

EDIT2:* 我有一些工作要做,但我认为我创造了一个怪物。我不认为这应该是这样:

export const getUserGroups = () => {
  return (dispatch) => {
    dispatch({ type: GET_USERS_GROUPS });
    const uid = firebase.auth().currentUser.uid;
    firebase.database().ref(`/userGroups/${uid}/`)
      .on('value', snapshot => {
        const promises = [];
        const groupArr = [];
        const messages = [];
        snapshot.forEach(child => {
          const children = child.val();
          const groupId = children.groupId;
          const promise = getGroupImages(groupId)
          .then(url => {
            children.img = url;
            return children;
          })
          .catch(e => console.log(e));
          promises.unshift(promise);
        }); // </foreach>
        Promise.all(promises)
        .then(children => { // child === array with both objects
          const messages = [];
          children.map(child => {
            const groupId = child.groupId;
            const ch = child;
            const message = getLastMessages(groupId)
            .then(msg => {
              ch.lastMsg = msg;
              return ch;
            })
            .catch((e) => console.log(e));
            messages.unshift(message);
          }); // .map
          Promise.all(messages)
          .then((bla) => {
            dispatch({ type: GET_USERS_GROUPS_SUCCESS, payload: bla });
          });
        });
      });
  };
};

编辑1 在“ harshiL shah”的帮助下,我成功实现了诺言。但是,即使有许诺返回的图像,groupArr仍然为空。

snapshot.forEach(child => {
 const children = child.val();
 const groupId = children.groupId;
 getGroupImages(groupId).then((image) => {
  console.log(image); // url is showing
  children.image = image;
  const promise = firebase
    .database()
    .ref(`/groups/${groupId}/lastmessage`)
    .once('value')
    .then(snap => {
     children.lastmessage = snap.val();
     return children;
    });
     promises.unshift(promise);
    });
    });
    Promise.all(promises)
    .then(groupArr => {
    console.log('groupArr');
    console.log(groupArr); // [] empty Array
    dispatch({ type: GET_USERS_GROUPS_SUCCESS, payload: groupArr });

})

1 个答案:

答案 0 :(得分:1)

你过去了 () => (resolve, reject) => { some code }在承诺中,实际上是

function() {
    return function(resolve, reject) {
        some code
    }
}

实际上需要做的是

function(resolve, reject) {
    some code
}

(resolve, reject) => { some code }

请改用以下代码。

const getGroupImages = (groupId) => {
    return new Promise((resolve, reject) => {
        const ref = firebase.storage().ref(`images/${groupId}/groupImg`);
        ref.getDownloadURL()
        .then((image) => {
            resolve(image);
            })
        .catch((e) => reject(e));
    })
    .catch((err) => console.log(err));
};

这是我可以在您的代码中找到的唯一问题。我本来会对此发表评论,但是我没有足够的声誉。

--------------进行新修改的答案----------------

要了解该问题,请说从Firebase获取图像需要1分钟的时间。 snapshot.foreach甚至会在getGroupImages()完成获取第一个图像之前完成其执行,只有在它进入之后,然后进行阻塞,并将获取消息的承诺添加到promises数组中。因此,在调用Promise.all(promises)时,promises是一个空数组,然后在then块中得到空array(groupArr)。为了验证这一理论,您可以在Promise.all()之前打印promise数组。

下面是在这种情况下应该起作用的修复程序。

snapshot.forEach(child => {
    const children = child.val();
    const groupId = children.groupId;
    promise = getGroupImages(groupId)
    .then((image) => {
      children.image = image;
      return firebase
        .database()
        .ref(`/groups/${groupId}/lastmessage`)
        .once('value');
    })
    .then(snap => {
      children.lastmessage = snap.val();
      return children;
    })
    .catch((e) => console.log(e));
    promises.unshift(promise);
  });

我没有任何方法可以验证上面的代码是否正常工作。因此,请将其视为伪代码并进行必要的调整。