You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase聊天按日期分组报错:期望DocumentReference却传入数组

按日期分组的Firebase聊天功能报错解决

需求与问题

需要实现按日期分组的聊天功能,基于Firebase后端,数据结构为:

  • 集合chats -> 目标文档(ID示例:2h73gbu3id933jeif883ue9)
  • 文档内messages字段格式:[{date: 时间戳, m: [消息对象数组]}]

逻辑要求:

  • 若消息属于已有日期分组,在对应m数组中添加新消息
  • 若为新日期,新增一个{date: 当前时间戳, m: [新消息]}对象

用户编写的代码如下:

const today = new Date();
const currentDay = today.toLocaleDateString("en-US", { weekday: "long" });

const docRef = doc(db, "chats", chat.chatId);
const docSnap = await getDoc(docRef);
const currentMessages = docSnap.data()?.messages || [];

const lastMessageDate =
  currentMessages.length > 0 &&
  currentMessages[currentMessages.length - 1].date.toDate();
const isSameDay =
  lastMessageDate &&
  lastMessageDate.toLocaleDateString("en-US", { weekday: "long" }) ===
    currentDay;

if (!isSameDay) {
  await updateDoc(docRef, {
    messages: arrayUnion({
      date: Timestamp.now(),
      m: [{ uid: currentUser.uid, text: message, isSender: true }],
    }),
  });
} else {
  const updatedItems = [
    ...currentMessages[currentMessages.length - 1].m,
    { uid: currentUser.uid, text: message, isSender: true },
  ];
  await updateDoc(currentMessages, {
    messages: arrayUnion({
      date: lastMessageDate,
      m: updatedItems,
    }),
  });
}

执行isSameDay为true的逻辑时,出现报错:

'index.tsx:64 Uncaught (in promise) FirebaseError: Expected type 'DocumentReference', but it was: an array'

错误原因

  1. 参数类型错误:updateDoc的第一个参数必须是Firebase的DocumentReference对象,但else分支中传入了currentMessages(从文档读取的数组),导致类型不匹配。
  2. 逻辑错误:用arrayUnion更新已有日期的消息是错误的,arrayUnion的作用是向数组添加新的独立元素,无法修改数组中已存在对象的属性。

修正后的代码

const today = new Date();
const currentDay = today.toLocaleDateString("en-US", { weekday: "long" });

const docRef = doc(db, "chats", chat.chatId);
const docSnap = await getDoc(docRef);
const currentMessages = docSnap.data()?.messages || [];

const lastMessageDate = currentMessages.length > 0 
  ? currentMessages[currentMessages.length - 1].date.toDate() 
  : null;
const isSameDay = lastMessageDate && 
  lastMessageDate.toLocaleDateString("en-US", { weekday: "long" }) === currentDay;

if (!isSameDay) {
  // 新日期,添加分组
  await updateDoc(docRef, {
    messages: arrayUnion({
      date: Timestamp.now(),
      m: [{ uid: currentUser.uid, text: message, isSender: true }],
    }),
  });
} else {
  // 已有日期,更新对应分组的消息列表
  // 复制原数组,避免直接修改原数据
  const updatedMessages = [...currentMessages];
  // 替换最后一个分组的m数组
  updatedMessages[updatedMessages.length - 1] = {
    ...updatedMessages[updatedMessages.length - 1],
    m: [
      ...updatedMessages[updatedMessages.length - 1].m,
      { uid: currentUser.uid, text: message, isSender: true }
    ]
  };
  // 直接更新整个messages数组
  await updateDoc(docRef, { messages: updatedMessages });
}

关键修改说明

  • 确保updateDoc始终传入正确的docRef(文档引用)
  • 对于已有日期的场景,重新构造整个messages数组,修改最后一个分组的m元素后,直接替换文档中的messages字段
  • 避免使用arrayUnion修改已有元素,改用完全更新数组的方式

内容的提问来源于stack exchange,提问作者user21209760

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:27:41