我正在尝试通过将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()-这是我如何实现实时更新?
我已经搜索了所有可能的东西,但是找不到任何东西。
如果需要其他内容,我将对其进行更新。
答案 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操作要慢一点。
如果您需要帮助,请告诉我。