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

Firebase docData流连续触发相同对象重复发射问题

问题:Angular Fire Firestore的docData Observable重复发射相同内容

代码示例

import { doc, docData } from '@angular/fire/firestore';

const gameDocRef = doc(this.firestore, 'game', game.id);
const game$ = docData(gameDocRef, { idField: 'id' })

现象与确认信息

game$ observable会连续两次发射完全相同的内容,已通过日志验证以下细节:

  • 流仅创建一次
  • 两次发射的是完全相同的深度拷贝对象
  • 仅向Firestore后端发起一次请求,却触发两次相同发射

核心顾虑

虽然可以通过distinctUntilXChanged操作符过滤重复发射,但根据Firestore的配额规则,这两次发射仍会被算作独立读取,不想产生不必要的双倍费用。

重复内容验证方式

最初使用JSON序列化对比对象:

const currentGameJSON = JSON.stringify(currentGame);
const newGameJSON = JSON.stringify(game);
if (currentGameJSON === newGameJSON) {
  console.error("SAME GAME EMISSION", currentGameJSON);
}

文档为简单JSON结构,无递归属性或特殊格式,且未启用Firestore持久化功能。

补充说明

目前改用自定义深比较函数检查对象一致性:

function deepEqual(obj1: any, obj2: any): boolean {
  if (obj1 === obj2) return true;

  if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
    return false;
  }

  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  if (keys1.length !== keys2.length) return false;

  for (let key of keys1) {
    if (!keys2.includes(key)) return false;

    if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
      if (!deepEqual(obj1[key], obj2[key])) return false;
    } else if (obj1[key] !== obj2[key]) {
      return false;
    }
  }

  return true;
}

内容的提问来源于stack exchange,提问作者frontend-ux-ui

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:43:11