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

Ember.js结合Firebase开发聊天,数据库新增消息后如何实时更新?

问题原因

你当前使用的Ember Data findAll('chat-message') 是一次性查询方法,仅会在路由加载时拉取一次历史消息,没有监听Firebase的实时数据推送事件。当其他客户端发送新消息到Firebase后,本地Ember Store不会自动同步新数据,因此绑定了Store数据的页面不会自动刷新。

解决方案

核心是给聊天消息集合添加Firebase实时监听器,监听到新消息后主动同步到本地Ember Store,借助Ember的响应式能力自动刷新页面。你不需要修改现有模板代码,仅需要调整路由层的逻辑:

1. Cloud Firestore 版本适配

修改routes/show-messages.js代码如下:

//routes/show-messages.js
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class ShowMessagesRoute extends Route {
  @service store;
  @service firebase;
  // 保存取消监听的函数,旧版Ember可改为普通属性不用#前缀
  #unsubscribeListener = null;

  async model() {
    // 先拉取历史消息初始化Store
    await this.store.findAll('chat-message');
    
    const db = this.firebase.firestore();
    // 开启消息集合的实时变更监听
    this.#unsubscribeListener = db.collection('chat-messages').onSnapshot(snapshot => {
      snapshot.docChanges().forEach(change => {
        // 仅处理新增的消息
        if (change.type === 'added') {
          // 将Firebase返回的新消息同步到本地Ember Store
          this.store.push({
            data: {
              id: change.doc.id,
              type: 'chat-message',
              attributes: change.doc.data()
            }
          });
        }
      });
    });

    // 返回Store中的消息集合,是响应式对象,数据变更会自动触发模板更新
    return this.store.peekAll('chat-message');
  }

  // 路由离开时销毁监听,避免内存泄漏
  deactivate() {
    if (this.#unsubscribeListener) {
      this.#unsubscribeListener();
    }
  }
}

2. 实时数据库(Realtime Database)版本适配

如果你使用的是Firebase实时数据库而非Cloud Firestore,将上述监听逻辑替换为以下代码即可:

const dbRef = this.firebase.database().ref('chat-messages');
this.#unsubscribeListener = dbRef.on('child_added', snapshot => {
  this.store.push({
    data: {
      id: snapshot.key,
      type: 'chat-message',
      attributes: snapshot.val()
    }
  });
});

// 对应取消监听的逻辑调整为
// deactivate() {
//   if (this.#unsubscribeListener) {
//     this.firebase.database().ref('chat-messages').off('child_added', this.#unsubscribeListener);
//   }
// }
注意事项
  • 确保你项目中app/models/chat-message.js里定义的属性和你存入Firebase的字段(text、username等)完全对应,否则同步到Store的时候会丢失字段
  • 你现有的ChatInput组件不需要修改,只要它能正确把消息写入Firebase,监听器就会自动捕获到新数据同步到所有在线客户端

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:24:07