Support chat with Angular + Firebase Realtime Database

Image for post
Image for post
Angular + Firebase Realtime Database
Image for post
Image for post
The message structure (this is one message)
ng new support-chat
npm i @angular/fire — save
app.module.tsimport { AngularFireModule } from ‘@angular/fire’;
import { AngularFireDatabaseModule } from ‘@angular/fire/database’;
imports: [
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFireDatabaseModule,

]
ng g c components/chat
ng g s components/chat/chat
chat.service.tsimport { Injectable, OnInit } from '@angular/core';import { AngularFireDatabase, AngularFireObject } from '@angular/fire/database';
chat.service.tsconstructor(private db: AngularFireDatabase){}
chat.service.tsgetMessagesList() {  
return this.db.object('Chat').valueChanges();
}
chat.component.tsthis.chatService.getMessagesList().subscribe(messagesList => {
this.messagesList = messagesList;
this.usersList = Object.keys(this.messagesList).map(val => {
return val;
});
});
chat.component.html<div class="position-relative"
*ngFor="let user of searchableList"
(click)="showChat(user.firebaseId, $event);
getChat(user.firebaseId)"
>
<div class="overlay"
*ngIf="messagesList[user.firebaseId]['meta-data']?.agent && !
(messagesList[user.firebaseId]['meta-data']?.agent?.name == '')"

>
<p class="overlay-text">{{ messagesList[user.firebaseId]['meta
-data']?.agent?.name }} is typing...</p>
</div>
<div class="messages-section row cp m-0 px-2">
<div
class="col-2 px-0 prof-img"
[ngStyle]="{
background: 'url(' + user?.profileImage ||
'../../../../assets/images/user.svg' + ')',
'background-position': 'center',
'background-size': 'cover'
}"
></div>
<div class="col-10 align-self-center">
<p class="name">{{ user?.name }}</p>
<p class="message" [ngClass]="messagesList[user.firebaseId] ['meta-data']?.user.new ? 'bold-text' : ''">
{{ getLatestMessage(messagesList[user.firebaseId]) }}
</p>
<p class="message text-right">
{{ getLatestMessageTime(messagesList[user.firebaseId]) | timeAgo }}
</p>
</div>
</div>
chat.service.tsgetMessages(user) {
return this.db
.list('Chat/' + user + '/messages', ref => {
return ref.orderByChild('timeStamp');
})
.valueChanges();
}
chat.component.tspostMessage() {
const user = {
id: this.agent._id,
name: this.agent.name
};
this.chatService.sendMessage(user, this.chatMessage, this.selectedUser);
}
chat.service.tssendMessage(user, message, chatID) {
const messageData = {
senderID: user.id,
messageBody: message,
senderName: user.name,
timeStamp: new Date().getTime()
};
const agentMeta = {
name: user.name,
new: true
};
const userMeta = {
new: false
};
this.db.list(`Chat/${chatID}/messages`).push(messageData);
this.db.database.ref(`Chat/${chatID}/meta-data/agent`).update(agentMeta);
this.db.database.ref(`Chat/${chatID}/meta-data/user`).update(userMeta);
}
chat.component.tsendConversation() {
this.chatService.endConversation(this.selectedUser);
}
chat.service.tsendConversation(chatID) {
const agentMeta = {
name: '',
new: false
};
const userMeta = {
new: false
};
this.db.database.ref(`Chat/${chatID}/meta-data/agent`).update(agentMeta);
this.db.database.ref(`Chat/${chatID}/meta-data/user`).update(userMeta);
}

ReactJS, NextJS, NodeJS and every other JS! It’s like a never ending learning journey. 😎

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store