为什么 react-native-gifted-chat 不能正确显示来自 firebase 时间戳的时间?

Why react-native-gifted-chat not displaying time correctly from firebase timestamp?

我在我的应用程序中使用 react-native-gifted-chat 添加聊天功能。目前我能够正确地发送和接收来自 firebase 的消息。但是,问题是 react-native-gifted-chat 总是显示消息发送时间的 12:00 上午。这是因为它无法将 firebase 时间戳转换为时间。谁能帮我解决一下?

这是我使用 GiftedChat 组件的方式:

<GiftedChat
  messages={this.props.messages}
  renderUsernameOnMessage={true}
  onSend={messages => this.onSend(messages)}
  alwaysShowSend={true}
  textInputStyle={styles.composer}
  minComposerHeight={40}
  minInputToolbarHeight={60}
  user={{
    _id: this.props.account ?.user ?.uid,
    name: this.props.account ?.data ?.fullName,
    avatar: this.props.account ?.data ?.avatar
  }}
/>

下面是我用于在 firestore 中保存消息的代码:

export const sendMessage = (message, groupId) => {
  return async () => {
    await firestore().collection('groupMessages').doc(groupId).collection('messages').doc(message._id).set(message).catch((e) => {
      throw {message: e.message.replace(`[${e.code}] `, '')}
    });
  }
}

在上面的代码中 message 是一个有天赋的聊天消息,它包含属性:_idtextcreatedAtuser

消息在 firebase 中的存储方式如下:

当我显示消息时:

临时解决方案终于完成了。我通过 renderTime 道具自定义渲染时间来解决它。

<GiftedChat
  ...
  renderTime={(props) => (
    <View style={props.containerStyle}>
      <CText size={10} style={{marginHorizontal: 10, marginBottom: 5}} bold color={props.position === "left" ? 'gray' : 'white'}>
        {`${props.currentMessage.createdAt.toDate().toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true })}`}
      </CText>
    </View>
  )}
  ...
  ...
/>

我已经将 createdAt 转换为日期,然后在 hh:mm AM/PM 格式中获取它。

注意:这只是变通解决方案,如果您在本地存储消息和显示消息可能不起作用,因为 GiftedChat 生成的消息字段 createdAt 是纯 javascript 没有 toDate() 函数的日期对象,因此您可能会遇到此类错误。

Uncaught TypeError: (intermediate value).toDate is not a function at :1:12

根据我的个人经验,解决这个问题最简单的方法是在使用 [=14] 将数据保存到 firebase 之前将 createdAt 时间 属性 转换为 milliseconds =] 方法。由于 react-native-gifted-chat 生成具有不同时间 属性 格式的 message 对象,即 "createdAt": 2020-05-08T06:56:44.698Z。但是当这个 属性 保存到 firebase 中时,它在那里显示为 timestamp,当我们从 firebase 中获取数据时,它 returns 属性 createdAt 具有不同的格式,即 "createdAt": {"_nanoseconds": 943000000, "_seconds": 1588921685}。 这导致了问题,应用程序始终显示当前日期和时间 12:00 AM。所以简单的解决方案是在将日期格式保存到 firebase 之前更改日期格式:

const saveMessage = async (message) => {
    const temp = message[0];

    const createdAt = Date.parse(temp.createdAt); //<--- add this line

    const a = await db.add({ ...temp, createdAt });

    //---------your other code--------//
  }

现在,当您从 firebase 获取数据时,您的应用程序将显示正确的日期和时间。

我用这个想法解决了这个问题也可以用。

firestore()
      .collection('Messages')
      .where('experienceId', '==', experienceId)
      .orderBy('createdAt', 'desc')
      .get()
      .then(function (querySnapshot) {
        var messagesAll = [];
        querySnapshot.forEach(function (documentSnapshot) {
          messagesAll.push({
            _id: documentSnapshot.data()._id,
            text: documentSnapshot.data().text,
            createdAt: new Date(documentSnapshot.data().createdAt.toDate()),
            user: documentSnapshot.data().user,
          });
        });
        setMessages(messagesAll);
      });