Firebase Integration

Akita as a Real-Time state manager

Articles About Angular Akita and Firebase

Akita Ng Fire

akita-ng-fire simplifies the connection between Akita and Firebase inside an Angular project.

Installation

ng add @angular/fire
npm install akita-ng-fire

Getting Started

First, create a new entity feature with Akita :

ng g feature movies/movie

In your movie.store.ts, extend the MovieState with CollectionState:

export interface MovieState extends CollectionState<Movie> {}

Then in your movie.service.ts add the following code:

import { Injectable } from '@angular/core';
import { MovieStore, MovieState } from './movie.store';
import { AngularFirestore } from '@angular/fire/firestore';
import { CollectionConfig, CollectionService } from 'akita-ng-fire';
@Injectable({ providedIn: 'root' })
@CollectionConfig({ path: 'movies' })
export class MovieService extends CollectionService<MovieState> {
constructor(store: MovieStore) {
super(store);
}
}

The CollectionConfig decorator takes the path to our collection in Firestore. We extend the CollectionService passing a reference to the Firestore database and our store.

The Component

In your component you can now start listening on Firebase :

@Component({
selector: 'app-root',
template: `
<ul>
<li *ngFor="let movie of movies$ | async">{{ movie.title }}</li>
<button (click)="add()">Add a Movie</button>
</ul>
`
})
export class AppComponent implements OnInit, OnDestroy {
private sub: Subscription;
public movies$: Observable<Movie[]>;
constructor(private service: MovieService,
private query: MovieQuery) {}
ngOnInit() {
// Subscribe to the collection
this.sub = this.service.syncCollection().subscribe();
// Get the list from the store
this.movies$ = this.query.selectAll();
}
ngOnDestroy() {
this.sub.unsubscribe();
}
// Add to Firestore's movie collection
add() {
this.service.add({ title: 'Star Wars' });
}
}

Using a Guard (alternative to ngOnDestroy)

Alternatively, you can use a Guard to manage your subscriptions/unsubscriptions :

First create a new movie.guard.ts:

@Injectable({ providedIn: 'root' })
export class MovieGuard extends CollectionGuard<MovieState> {
constructor(service: MovieService) {
super(service);
}
}

In your movie.module.ts

@NgModule({
declarations: [HomeComponent, MovieListComponent]
imports: [
RouterModule.forChild([
{ path: '', component: HomeComponent },
{
path: 'movie-list',
component: MovieListComponent,
canActivate: [MovieGuard], // start sync (subscribe)
canDeactivate: [MovieGuard], // stop sync (unsubscribe)
}
])
]
})
export class MovieModule {}