WIP: Use firebase as a backend for the app

This commit is contained in:
William Brawner 2018-12-18 08:59:01 -06:00
parent da7a7c94f6
commit 279d644a2e
11 changed files with 810 additions and 112 deletions

785
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -26,6 +26,7 @@
"@angular/service-worker": "^6.1.0", "@angular/service-worker": "^6.1.0",
"core-js": "^2.5.4", "core-js": "^2.5.4",
"dexie": "^2.0.4", "dexie": "^2.0.4",
"firebase": "^5.5.8",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"ng2-currency-mask": "^5.3.1", "ng2-currency-mask": "^5.3.1",
"rxjs": "^6.0.0", "rxjs": "^6.0.0",

View file

@ -1,7 +1,9 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http'; import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs'; import { Observable, of, from } from 'rxjs';
import { Transaction } from './transaction'; import { Transaction } from './transaction';
import * as firebase from 'firebase/app';
import 'firebase/database';
const httpOptions = { const httpOptions = {
headers: new HttpHeaders({ headers: new HttpHeaders({
@ -52,10 +54,16 @@ export class ApiService {
} }
getTransactions(): Observable<any> { getTransactions(): Observable<any> {
return this.http.get( return Observable.create(subscriber => {
host + '/transactions', const transactionsRef = firebase.database().ref('transactions');
httpOptions transactionsRef.on('child_changed', data => {
); if (!data.val()) {
return;
}
subscriber.next(data.val());
});
});
} }
saveTransaction(transaction: Transaction): Observable<Transaction> { saveTransaction(transaction: Transaction): Observable<Transaction> {

View file

@ -3,9 +3,9 @@
<mat-nav-list (click)="sidenav.close()"> <mat-nav-list (click)="sidenav.close()">
<a mat-list-item routerLink="/accounts">Manage Accounts</a> <a mat-list-item routerLink="/accounts">Manage Accounts</a>
<a mat-list-item (click)="exportData()">Export Data</a> <a mat-list-item (click)="exportData()">Export Data</a>
<a mat-list-item *ngIf="!authService.currentUser" routerLink="/login">Login</a> <a mat-list-item *ngIf="!isLoggedIn()" routerLink="/login">Login</a>
<a mat-list-item *ngIf="!authService.currentUser" routerLink="/register">Register</a> <a mat-list-item *ngIf="!isLoggedIn()" routerLink="/register">Register</a>
<a mat-list-item *ngIf="authService.currentUser" (click)="logout()">Logout</a> <a mat-list-item *ngIf="isLoggedIn()" (click)="logout()">Logout</a>
</mat-nav-list> </mat-nav-list>
</mat-sidenav> </mat-sidenav>
<mat-sidenav-content> <mat-sidenav-content>

View file

@ -3,6 +3,8 @@ import { Location } from '@angular/common';
import { Actionable } from './actionable'; import { Actionable } from './actionable';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { BudgetDatabase } from './budget-database'; import { BudgetDatabase } from './budget-database';
import * as firebase from 'firebase/app';
import 'firebase/auth';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
@ -18,7 +20,17 @@ export class AppComponent {
public authService: AuthService, public authService: AuthService,
private location: Location, private location: Location,
private db: BudgetDatabase, private db: BudgetDatabase,
) { } ) {
const config = {
apiKey: 'AIzaSyALYI-ILmLV8NBNXE3DLF9yf1Z5Pp-Y1Mk',
authDomain: 'budget-c7da5.firebaseapp.com',
databaseURL: 'https://budget-c7da5.firebaseio.com',
projectId: 'budget-c7da5',
storageBucket: 'budget-c7da5.appspot.com',
messagingSenderId: '527070722499'
};
firebase.initializeApp(config);
}
goBack(): void { goBack(): void {
this.location.back(); this.location.back();
@ -43,4 +55,8 @@ export class AppComponent {
window.URL.revokeObjectURL(url); window.URL.revokeObjectURL(url);
}); });
} }
isLoggedIn() {
return firebase.auth().currentUser != null;
}
} }

View file

@ -36,8 +36,9 @@ import { AddEditAccountComponent } from './add-edit-account/add-edit-account.com
import { EditProfileComponent } from './edit-profile/edit-profile.component'; import { EditProfileComponent } from './edit-profile/edit-profile.component';
import { UserComponent } from './user/user.component'; import { UserComponent } from './user/user.component';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { CurrencyMaskModule } from "ng2-currency-mask"; import { CurrencyMaskModule } from 'ng2-currency-mask';
import { CurrencyMaskConfig, CURRENCY_MASK_CONFIG } from "ng2-currency-mask/src/currency-mask.config"; import { CurrencyMaskConfig, CURRENCY_MASK_CONFIG } from 'ng2-currency-mask/src/currency-mask.config';
import * as firebase from 'firebase/app';
export const CustomCurrencyMaskConfig: CurrencyMaskConfig = { export const CustomCurrencyMaskConfig: CurrencyMaskConfig = {
align: 'left', align: 'left',

View file

@ -2,52 +2,42 @@ import { Injectable } from '@angular/core';
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import { User } from './user'; import { User } from './user';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import * as firebase from 'firebase/app';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class AuthService { export class AuthService {
public currentUser: User;
constructor( constructor(
private apiService: ApiService, private apiService: ApiService,
private router: Router, private router: Router,
) { } ) { }
login(user: User) { login(email: string, password: string) {
this.apiService.login(user.name, user.password).subscribe( firebase.auth().signInWithEmailAndPassword(email, password).then(value => {
value => {
this.currentUser = value;
this.router.navigate(['/']); this.router.navigate(['/']);
}, }).catch(err => {
error => {
console.log('Login failed'); console.log('Login failed');
console.log(error); console.log(err);
} });
);
} }
register(user: User) { // register(user: User) {
this.apiService.register(user.name, user.email, user.password).subscribe( // this.apiService.register(user.name, user.email, user.password).subscribe(
value => { // value => {
this.login(value); // this.login(value);
}, // },
error => { // error => {
console.log('Registration failed'); // console.log('Registration failed');
console.log(error); // console.log(error);
} // }
); // );
} // }
logout() { logout() {
this.apiService.logout().subscribe( firebase.auth().signOut().then(value => {
value => {
window.location.reload(); window.location.reload();
}, });
error => {
console.log('Logout failed');
console.log(error);
}
);
} }
} }

View file

@ -39,7 +39,7 @@ export class DashboardComponent implements OnInit {
} }
getTransactions(): void { getTransactions(): void {
this.transactionService.getTransactions(5).subscribe(transactions => this.transactions = transactions) this.transactionService.getTransactions(5).subscribe(transactions => this.transactions = <Transaction[]> transactions);
} }
getCategories(): void { getCategories(): void {

View file

@ -1,8 +1,8 @@
<div class="form login-form"> <div class="form login-form">
<mat-form-field> <mat-form-field>
<input matInput placeholder="Username" [(ngModel)]="user.name" /> <input matInput placeholder="Email" [(ngModel)]="email" />
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<input matInput type="password" placeholder="Password" [(ngModel)]="user.password" /> <input matInput type="password" placeholder="Password" [(ngModel)]="password" />
</mat-form-field> </mat-form-field>
</div> </div>

View file

@ -11,7 +11,8 @@ import { AppComponent } from '../app.component';
}) })
export class LoginComponent implements OnInit, OnDestroy, Actionable { export class LoginComponent implements OnInit, OnDestroy, Actionable {
public user: User = new User(); public email: string;
public password: string;
constructor( constructor(
private app: AppComponent, private app: AppComponent,
@ -29,7 +30,7 @@ export class LoginComponent implements OnInit, OnDestroy, Actionable {
} }
doAction(): void { doAction(): void {
this.authService.login(this.user); this.authService.login(this.email, this.password);
} }
getActionLabel() { getActionLabel() {

View file

@ -5,6 +5,7 @@ import { TransactionType } from './transaction.type';
import { BudgetDatabase, ITransaction } from './budget-database'; import { BudgetDatabase, ITransaction } from './budget-database';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import * as firebase from 'firebase/app';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -19,22 +20,15 @@ export class TransactionService {
getTransactions(count?: number): Observable<ITransaction[]> { getTransactions(count?: number): Observable<ITransaction[]> {
// Check if we have a currently logged in user // Check if we have a currently logged in user
if (this.authService.currentUser) { if (!firebase.auth().currentUser) {
this.apiService.getTransactions().subscribe(
value => {
console.log(value);
},
error => {
console.error(error);
}
);
}
if (count) { if (count) {
return from(this.db.transactions.orderBy('date').reverse().limit(count).toArray()); return from(this.db.transactions.orderBy('date').reverse().limit(count).toArray());
} else { } else {
return from(this.db.transactions.orderBy('date').reverse().toArray()); return from(this.db.transactions.orderBy('date').reverse().toArray());
} }
} }
return this.apiService.getTransactions();
}
getTransaction(id: number): Observable<Transaction> { getTransaction(id: number): Observable<Transaction> {
return Observable.create(subscriber => { return Observable.create(subscriber => {
@ -53,7 +47,7 @@ export class TransactionService {
saveTransaction(transaction: Transaction): Observable<Transaction> { saveTransaction(transaction: Transaction): Observable<Transaction> {
this.db.transactions.put(transaction); this.db.transactions.put(transaction);
if (this.authService.currentUser) { if (auth().currentUser) {
return this.apiService.saveTransaction(transaction); return this.apiService.saveTransaction(transaction);
} else { } else {
return of(transaction); return of(transaction);