July 10, 2021
Introduction
Real-time applications are everywhere today — from chat apps and collaborative tools to live notifications. Angular, combined with Firebase’s powerful backend-as-a-service (BaaS), makes building these apps fast and scalable.
In this tutorial, we’ll build a real-time chat application using:
- Angular (with RxJS Observables)
- AngularFire (the official Angular library for Firebase)
- Firebase Authentication for user login
- Cloud Firestore for storing messages
- Angular Material for sleek UI components
By the end, you’ll have a fully functional chat app with real-time message updates, user authentication, and a polished UI.
Prerequisites
- Basic Angular knowledge
- Node.js and Angular CLI installed
- Firebase project created in the Firebase Console
- Angular Material setup (we’ll cover this)
Step 1: Set Up Angular and Firebase
Create a new Angular app if you don’t have one:
ng new angular-chat-app --routing --style=scss
cd angular-chat-app
Install AngularFire and Firebase SDK:
npm install firebase @angular/fire
Step 2: Configure Firebase Project
In your Firebase Console:
- Create a new project (or use existing)
- Enable Authentication → Sign-in methods → Email/Password (or Google, etc.)
- Enable Cloud Firestore in test mode for now (secure rules later)
Get your Firebase config (found in project settings):
// src/environments/environment.ts
export const environment = {
production: false,
firebaseConfig: {
apiKey: 'YOUR_API_KEY',
authDomain: 'your-app.firebaseapp.com',
projectId: 'your-app',
storageBucket: 'your-app.appspot.com',
messagingSenderId: '...',
appId: '...'
}
};
Step 3: Initialize Firebase in Angular
In your AppModule
, import AngularFire modules:
import { AngularFireModule } from '@angular/fire/compat';
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore';
import { environment } from '../environments/environment';
@NgModule({
declarations: [...],
imports: [
BrowserModule,
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFireAuthModule,
AngularFirestoreModule,
// Other imports ...
],
bootstrap: [AppComponent]
})
export class AppModule { }
Step 4: Implement Authentication Service
Create a simple auth service for login/logout:
import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import firebase from 'firebase/compat/app';
@Injectable({ providedIn: 'root' })
export class AuthService {
user$ = this.afAuth.authState;
constructor(private afAuth: AngularFireAuth) {}
async login(email: string, password: string) {
return await this.afAuth.signInWithEmailAndPassword(email, password);
}
async logout() {
await this.afAuth.signOut();
}
async register(email: string, password: string) {
return await this.afAuth.createUserWithEmailAndPassword(email, password);
}
}
Step 5: Building the Chat Component
Create a chat component that displays messages and sends new ones:
ng generate component chat
Firestore Message Model
export interface ChatMessage {
id?: string;
text: string;
userId: string;
userName: string;
timestamp: firebase.firestore.FieldValue;
}
Chat Service to Manage Messages
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/compat/firestore';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class ChatService {
private messagesCollection: AngularFirestoreCollection<ChatMessage>;
messages$: Observable<ChatMessage[]>;
constructor(private afs: AngularFirestore) {
this.messagesCollection = afs.collection<ChatMessage>('messages', ref => ref.orderBy('timestamp', 'asc'));
this.messages$ = this.messagesCollection.valueChanges({ idField: 'id' });
}
sendMessage(message: ChatMessage) {
return this.messagesCollection.add(message);
}
}
Chat Component Template (chat.component.html
)
<div class="chat-container">
<div class="messages">
<div *ngFor="let msg of messages$ | async" class="message">
<strong>{{ msg.userName }}:</strong> {{ msg.text }}
</div>
</div>
<form (ngSubmit)="sendMessage()" #chatForm="ngForm">
<mat-form-field class="full-width">
<input matInput placeholder="Type a message" [(ngModel)]="newMessage" name="message" required />
</mat-form-field>
<button mat-raised-button color="primary" type="submit" [disabled]="chatForm.invalid">Send</button>
</form>
</div>
Chat Component Logic (chat.component.ts
)
import { Component } from '@angular/core';
import { ChatService } from '../services/chat.service';
import { AuthService } from '../services/auth.service';
import firebase from 'firebase/compat/app';
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.scss']
})
export class ChatComponent {
messages$ = this.chatService.messages$;
newMessage: string = '';
currentUser: any;
constructor(private chatService: ChatService, private authService: AuthService) {
this.authService.user$.subscribe(user => {
this.currentUser = user;
});
}
async sendMessage() {
if (!this.newMessage.trim()) return;
const message = {
text: this.newMessage,
userId: this.currentUser.uid,
userName: this.currentUser.email,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
};
await this.chatService.sendMessage(message);
this.newMessage = '';
}
}
Step 6: Adding Angular Material UI
Install Angular Material:
ng add @angular/material
Import Material modules in your AppModule
:
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
@NgModule({
imports: [
MatFormFieldModule,
MatInputModule,
MatButtonModule,
// ...
],
})
export class AppModule { }
Step 7: User Authentication UI
Create simple login and registration components to handle user auth (omitted here for brevity). Bind these to AuthService
methods.
Final Thoughts and Next Steps
Congratulations! You now have a real-time chat app powered by Angular and Firebase.
What you can add next:
- User presence indicators
- Message read receipts
- Typing indicators
- Push notifications
Firebase and AngularFire handle scalability and real-time updates, making this a solid foundation.