Add firebase collection and transaction item

This commit is contained in:
Garrett Mills 2021-04-10 00:47:05 -05:00
parent b81e571901
commit 5734863c7a
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246
4 changed files with 104 additions and 2 deletions

View File

@ -0,0 +1,65 @@
import {Inject, Injectable} from "@extollo/di"
import {Collection, Iterable} from "@extollo/util"
import {FirebaseUnit, RTDBRef} from "./units/FirebaseUnit"
import * as firebase from "firebase-admin"
import {Application} from "@extollo/lib";
export interface FirebaseResourceItem {
seqID: number
}
@Injectable()
export class FirebaseResource<T extends FirebaseResourceItem> extends Iterable<T> {
protected refName!: RTDBRef
ref(): firebase.database.Reference {
return Application.getApplication().make<FirebaseUnit>(FirebaseUnit).ref(this.refName)
}
async getNextID(): Promise<number> {
return new Promise<number>((res, rej) => {
this.ref().orderByChild('seqID')
.on('value', snapshot => {
res(this.resolveObject(snapshot.val()).reverse()?.[0]?.seqID || 1)
}, rej)
})
}
async at(i: number): Promise<T | undefined> {
return new Promise<T | undefined>((res, rej) => {
this.ref().orderByChild('seqID')
.startAt(i).endAt(i)
.on('value', snapshot => res(this.resolveObject(snapshot.val())[0]), rej)
})
}
async range(start: number, end: number): Promise<Collection<T>> {
return new Promise<Collection<T>>((res, rej) => {
this.ref().orderByChild('seqID')
.startAt(start).endAt(end)
.on('value', snapshot => {
res(new Collection<T>(this.resolveObject(snapshot.val())))
}, rej)
})
}
async count(): Promise<number> {
return new Promise<number>((res, rej) => {
this.ref().orderByChild('seqID')
.on('value', snapshot => {
res(this.resolveObject(snapshot.val()).length)
}, rej)
})
}
protected resolveObject(snapshot: object | null | undefined) {
if ( !snapshot ) snapshot = {}
return Object.values(snapshot)
}
clone(): Iterable<T> {
const inst = new FirebaseResource<T>()
inst.refName = this.refName
return inst
}
}

View File

@ -10,6 +10,14 @@ export default {
.toString('utf-8') .toString('utf-8')
), ),
defaultRTDB: env('FIREBASE_DEFAULT_RTDB', 'https://loc-chain-default-rtdb.firebaseio.com'), api_auth_header: env('FIREBASE_API_AUTH_HEADER', 'X-Auth-Token'),
rtdb: {
default: env('FIREBASE_DEFAULT_RTDB', 'https://loc-chain-default-rtdb.firebaseio.com'),
refs: {
peers: 'chain/server/peers',
transaction: 'chain/pending/transactions',
},
},
} }
} }

View File

@ -0,0 +1,21 @@
import {FirebaseResource, FirebaseResourceItem} from "../FirebaseResource"
import {Injectable} from "@extollo/di"
import {RTDBRef} from "../units/FirebaseUnit"
import {AsyncCollection} from "@extollo/util";
export interface TransactionResourceItem extends FirebaseResourceItem {
combinedHash: string;
timestamp: number;
encodedGPSLocation: string;
partnerPublicKey: string;
validationSignature: string;
}
@Injectable()
export class TransactionResource extends FirebaseResource<TransactionResourceItem> {
public static collect(): AsyncCollection<TransactionResourceItem> {
return new AsyncCollection<TransactionResourceItem>(new TransactionResource())
}
protected refName: RTDBRef = 'transaction'
}

View File

@ -2,6 +2,8 @@ import {Singleton, Inject} from "@extollo/di"
import {Unit, Logging, Config} from "@extollo/lib" import {Unit, Logging, Config} from "@extollo/lib"
import * as firebase from "firebase-admin" import * as firebase from "firebase-admin"
export type RTDBRef = 'peers' | 'transaction'
/** /**
* FirebaseUnit Unit * FirebaseUnit Unit
* --------------------------------------- * ---------------------------------------
@ -21,12 +23,18 @@ export class FirebaseUnit extends Unit {
return this._firebase return this._firebase
} }
ref(name: RTDBRef): firebase.database.Reference {
return this._firebase.database().ref(
String(this.config.get(`app.firebase.rtdb.refs.${name}`))
)
}
/** Called on app start. */ /** Called on app start. */
public async up() { public async up() {
this.logging.info('Initializing Firebase application credentials...') this.logging.info('Initializing Firebase application credentials...')
this._firebase.initializeApp({ this._firebase.initializeApp({
credential: firebase.credential.cert(this.config.get('app.firebase.credentials')), credential: firebase.credential.cert(this.config.get('app.firebase.credentials')),
databaseURL: this.config.get('app.firebase.defaultRTDB'), databaseURL: this.config.get('app.firebase.rtdb.default'),
}) })
} }