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",
"core-js": "^2.5.4",
"dexie": "^2.0.4",
"firebase": "^5.5.8",
"hammerjs": "^2.0.8",
"ng2-currency-mask": "^5.3.1",
"rxjs": "^6.0.0",

View file

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

View file

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

View file

@ -3,6 +3,8 @@ import { Location } from '@angular/common';
import { Actionable } from './actionable';
import { AuthService } from './auth.service';
import { BudgetDatabase } from './budget-database';
import * as firebase from 'firebase/app';
import 'firebase/auth';
@Component({
selector: 'app-root',
@ -18,7 +20,17 @@ export class AppComponent {
public authService: AuthService,
private location: Location,
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 {
this.location.back();
@ -43,4 +55,8 @@ export class AppComponent {
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 { UserComponent } from './user/user.component';
import { HttpClientModule } from '@angular/common/http';
import { CurrencyMaskModule } from "ng2-currency-mask";
import { CurrencyMaskConfig, CURRENCY_MASK_CONFIG } from "ng2-currency-mask/src/currency-mask.config";
import { CurrencyMaskModule } from 'ng2-currency-mask';
import { CurrencyMaskConfig, CURRENCY_MASK_CONFIG } from 'ng2-currency-mask/src/currency-mask.config';
import * as firebase from 'firebase/app';
export const CustomCurrencyMaskConfig: CurrencyMaskConfig = {
align: 'left',

View file

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

View file

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

View file

@ -1,8 +1,8 @@
<div class="form login-form">
<mat-form-field>
<input matInput placeholder="Username" [(ngModel)]="user.name" />
<input matInput placeholder="Email" [(ngModel)]="email" />
</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>
</div>

View file

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

View file

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