我可以通过Firebase Cloud Functions实现聊天功能吗?

时间:2019-03-11 15:13:07

标签: angular firebase google-cloud-firestore google-cloud-functions

我正在尝试通过将Angular用于前端并将Cloud Function与Cloud Firestore用作后端来实现聊天功能。前端和Firestore仅通过Cloud Functions进行通信。顺便问一下,这是一个好方法吗?

我所知道的问题是,如果我的用户所在的聊天室之一收到新消息,则可以使我的前端实时更新。

一个聊天室仅限两个用户使用,但是一个用户可以与其他用户建立多个聊天室。

我的代码:

云功能:

chatroomsEndpoint.js:

const chatroomsCollection = db.collection("chatrooms");

exports.getAllChatroomsByUserId = async function (req, res) {
    try {
        let chatrooms = [];
        // console.log(req.params.user_id);

        const resultA = await chatroomsCollection.where("userA", "==", req.params.user_id).get();
        resultA.docs.map(chatroom => {
            return chatrooms.push(chatroom.data());
        })

        const resultB = await chatroomsCollection.where("userB", "==", req.params.user_id).get();
        resultB.docs.map(chatroom => {
            return chatrooms.push(chatroom.data());
        })

        return res.status(200).send(chatrooms);
    }
    catch (error) {
        console.log('Error getting chatrooms', error);
        return res.send(false);
    }
};

我在Postman上进行了尝试,并获得了当前用户所在的所有聊天室。

前端(带有角度)

chat.service.ts:

constructor(
    private authService: AuthService,
    private http: HttpClient,
    private router: Router
  ) {
    this.headers.append('Content-Type', 'application/json');
  }

  getAllChatroomsByUserId() {
    return this.http.get(`${this.apiUrl2}/${this.authService.getUser().uid}`);
  }

chatroom-list.component.ts:

userChats$;

  constructor(
    public authService: AuthService,
    public chatService: ChatService,
    public router: Router,
    public userStoreService: UserStoreService
  ) { }

  ngOnInit() {
    this.userChats$ = this.chatService.getAllChatroomsByUserId();
  }

chatroom-list.component.html:

<ul>
    <li *ngFor="let chatroom of userChats$ | async">
      <a [routerLink]="'/' + chatroom.id">{{ chatroom.id }} - {{ chatroom.messages.length }} Messages </a>
    </li>
  </ul>

在启动Web应用程序时,我得到的只是聊天中的消息数,但是如果我在Firestore中的文档中添加其他消息,则消息的值不会更新。

我尝试坚持使用Fireship的视频https://www.youtube.com/watch?v=LKAXg2drQJQ&t=440s中的示例,但是在视频中,他是通过Angular和Firestore之间的直接通信来实现的。 我也重建它,并使其工作。 同样在该示例中,使用了snapshotChanges()-这是我如何实现实时更新?

我已经搜索了所有可能的东西,但是找不到任何东西。

如果需要其他内容,我将对其进行更新。

2 个答案:

答案 0 :(得分:1)

我认为使用云功能无法实现您想要的方式。尽管有Firestore triggers for cloud functions,但您很快就会遇到一个更大的问题……如何将新事件从服务器发送回浏览器。

正如您在视频中看到的那样,他正在浏览器上使用Firestore侦听器(类似于.snapshotChanges ),以侦听从数据库触发的事件。之所以能在浏览器环境中运行,是因为Firebase在浏览器和服务器之间打开了一个websocket,从而允许了双方之间的实时通信……而更深层次的是,由于Firestore内置了websocket支持,因此可以正常工作。如果您想构建一个应用程序来侦听数据库,Firestore将允许您这样做。

不幸的是,云功能没有相同的功能。它们并不是像Firestore的websocket那样“保持开放”。实际上,如果您尝试一下,它们将在几分钟后超时...即使您调整了超时限制,您仍然会遇到其他问题...例如,如何处理断开的连接? ( Firestore websockets将自动尝试重新连接并重新打开该频道),哪些用户在听什么?等等...重点是,云功能的含义是简短,“执行一次”,一种服务...它们不会“保持开放”并继续在15岁以上的时间向客户端提供更新分钟的时间跨度。

长话短说,如果您希望浏览器从Firebase接收实时更新,则浏览器需要直接订阅那些Firestore事件-无云功能中间人-就像您在视频中看到的那样。

编辑:

This answer关于实时数据和云功能的问题还指出,云功能并不适合这种用例。

答案 1 :(得分:-1)

我的回答是,您可以使用Firebase云功能实现聊天功能。 不过这很容易,我已经借助一些rxjs功能实现了此聊天功能

是的,要使其成为实时的,但它的确比直接的Firebase操作要慢一点。

如果您需要帮助,请告诉我。