【问题标题】:Get data asynchronously from firebase and set state after the data is reached从firebase异步获取数据并在数据到达后设置状态
【发布时间】:2019-02-18 05:24:51
【问题描述】:

我正在使用 react-native,我想从 firebase 实时数据库中获取数据并设置该数据的状态,然后才加载视图,我不希望用户看到数据被推送和映射在每次加载聊天视图时。

这是我尝试过的

_getMessages = async () => {

    let message_array = [];

    await firebase.database().ref('User-Message').child(this.state.fromUser).child(this.state.toUser).on('child_added', async (snapshot) => {

      let message_id = await snapshot.key;

      let message_ref = await firebase.database().ref('Message').child(message_id).once('value', async (payload) => {

        await message_array.push(payload.val())

      })

      await this.setState({ messages : message_array })

    })

}

而在我的componentWillMount 中,只需像这样调用_getMessages() 函数

componentWillMount = async () => {

    await this._getMessages();

}

在从 firebase 获取所有消息后,如何确保设置消息的状态?

【问题讨论】:

  • 您是否在使用任何形式的状态管理? Redux 或 Mobx 会让这一切变得更简单。
  • 不,我不是 .. 这是我在 react-native 中的第一个项目,我明天必须交付,所以我没有时间尝试 redux ..

标签: reactjs firebase react-native async-await react-native-android


【解决方案1】:

这行不通:

await firebase.database().ref('User-Message').child(this.state.fromUser).child(this.state.toUser).on('child_added', async (snapshot) => {

Firebase 的 on() 方法开始主动侦听事件。它没有明确的完成时间,因此不返回承诺。因此它不能与await/async一起使用。

我的感觉是你试图简单地加载所有用户消息,使用once("value" 最容易做到这一点:

let ref = firebase.database().ref('User-Message').child(this.state.fromUser).child(this.state.toUser);
let message_array = await ref.once('value', async (snapshot) => {
  let messagePromises = [];
  snapshot.forEach(function(userMessageSnapshot) {
    messagePromises.push( firebase.database().ref('Message').child(snapshot.key).once('value', async (payload) => {
      return payload.val();
    })
  })
  await messageSnapshots = Promise.all(messagePromises);
  this.setState({ messages : messageSnapshots })
})

如果您想获得实时更新,则必须使用on() 侦听器。但这确实意味着您不能在外部侦听器中使用async/await。它看起来像这样:

let ref = firebase.database().ref('User-Message').child(this.state.fromUser).child(this.state.toUser);
ref.on('value', async (snapshot) => {
  let messagePromises = [];
  snapshot.forEach(function(userMessageSnapshot) {
    messagePromises.push( firebase.database().ref('Message').child(snapshot.key).once('value', async (payload) => {
      return payload.val();
    })
  })
  await messageSnapshots = Promise.all(messagePromises);
  this.setState({ messages : messageSnapshots })
})

【讨论】:

  • 这个方法会用 firebase 更新状态吗?我的意思是,如果我发送消息怎么办?
  • 你需要一个on() 监听器。它会正常工作,只是意味着你不能使用承诺或async/await。我也添加了一个样本。请注意,此代码中的拼写错误绝对是可能的。
猜你喜欢
  • 2020-06-01
  • 2020-04-01
  • 2021-04-10
  • 1970-01-01
  • 2017-11-29
  • 2017-03-14
  • 2020-09-19
  • 2021-05-16
  • 1970-01-01
相关资源
最近更新 更多