【问题标题】:Why react-native-gifted-chat not displaying time correctly from firebase timestamp?为什么 react-native-gifted-chat 不能从 firebase 时间戳正确显示时间?
【发布时间】:2020-03-31 11:21:11
【问题描述】:

我在我的应用程序中使用了react-native-gifted-chat 来添加聊天功能。目前我能够正确发送和接收来自 firebase 的消息。但是,问题是react-native-gifted-chat 总是显示 12:00 AM 的消息发送时间。这是因为它无法将 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 中的存储方式:

当我显示消息时:

【问题讨论】:

  • 如何在你的代码中保存 createdAt?分享它
  • 我编辑了关于如何保存 createdAt 的问题。

标签: javascript firebase react-native react-native-firebase react-native-gifted-chat


【解决方案1】:

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

<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

【讨论】:

    【解决方案2】:

    根据我个人的经验,解决这个问题最简单的方法是在将数据保存到firebase 之前,使用Date.parse() 方法将createdAt 时间属性转换为milliseconds。如react-native-gifted-chat 生成具有不同时间属性格式的message 对象,即"createdAt": 2020-05-08T06:56:44.698Z。但是当这个属性被保存到firebase 时,它会在那里显示为timestamp,当我们从firebase 获取数据时,它会返回具有不同格式的属性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 获取数据。

    【讨论】:

      【解决方案3】:

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

      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);
            });
      

      【讨论】: