【问题标题】:Firebase Real Time Database read dataFirebase 实时数据库读取数据
【发布时间】:2020-10-04 14:39:54
【问题描述】:

我正在使用 React + Redux 和 Firebase 的实时数据库构建类似 Messenger 的东西。

我习惯于从这样的 API 中检索数据:

export const fetchContacts = () => {
    return async dispatch => {
        dispatch(fetchContactsStart());

        try {
            const response = await axios.get('....');

            dispatch(fetchContactsSuccess(...));
        } catch(e) {
            dispatch(fetchContactsFail(...));
        }
    }
}

现在在 firebase 我有以下数据: enter image description here

我需要的是获取所有用户联系人,然后获取与这些联系人关联的用户信息并构建如下结构: [{电子邮件:...,用户名:...},{电子邮件:...,用户名:...},...]。在获得该格式的所有数据后,我想将操作分派给我的减速器。

现在我有以下代码:

export const fetchContacts = () => {
    return dispatch => {
        dispatch(fetchContactsStart());

        const userEmail = firebase.auth().currentUser.email;
        let data = [];

        firebase.database().ref(`users_contacts/${Base64.encode(userEmail)}`)
            .on('value', contacts => contacts.forEach(contact => {
                firebase.database().ref(`users/${Base64.encode(contact.val().contact)}`)
                    .on('value', user => {
                        data.push({ email: contact.val().contact, username: user.val().username });
                        console.log(data)
                    })
            }
        ))
    }
}

这可行,但我不知道如何仅在数据完全形成时才调度操作,有什么解决方案吗?感谢您的帮助!

【问题讨论】:

    标签: javascript reactjs firebase firebase-realtime-database redux


    【解决方案1】:

    当您等待多个异步操作完成时,解决方案通常是使用Promise.all。在这种情况下,它看起来像这样:

    export const fetchContacts = () => {
      return dispatch => {
        dispatch(fetchContactsStart());
    
        const userEmail = firebase.auth().currentUser.email;
        let data = [];
    
        firebase.database().ref(`users_contacts/${Base64.encode(userEmail)}`).once('value', contacts => {
          let promises = [];
          let map = {};
          contacts.forEach(contact => {
            const contactId = Base64.encode(contact.val().contact);
            map[contactId] = contact.val().contact;
            promises.push(firebase.database().ref(`users/${contactId}`).once('value'));
          });
          Promise.all(promises).then((users) => {
            users.forEach((user) =>
              data.push({ email: map[user.key], username: user.val().username });
            })
            // TODO: dispatch the result here
          }
        ))
      }
    }
    

    这里的主要变化:

    • 现在使用once() 加载用户数据,因此只加载一次并返回一个promise。
    • 使用Promise.all 等待所有配置文件都加载完毕。
    • 在内部回调中添加了一个地图来查找电子邮件地址。

    【讨论】:

    • 我想我必须在 then 中调度我的操作。除此之外,它确实按我需要的方式工作。非常感谢你拯救了我的一天!
    猜你喜欢
    • 1970-01-01
    • 2023-02-23
    • 2022-10-07
    • 2021-07-18
    • 2020-12-24
    • 2018-05-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多