Skip to content

Instantly share code, notes, and snippets.

@mizchi
Created March 14, 2017 07:15
Show Gist options
  • Save mizchi/7164f3067e5ba182523c9bb1537fff5d to your computer and use it in GitHub Desktop.
Save mizchi/7164f3067e5ba182523c9bb1537fff5d to your computer and use it in GitHub Desktop.
/* @flow */
import Observable from 'zen-observable'
import firebase from 'firebase'
import { firebaseConfig } from '../../config'
firebase.initializeApp(firebaseConfig)
type User = {}
let _currentUser
export function getCurrentUser (): Promise<?User> {
if (_currentUser) {
return Promise.resolve(_currentUser)
}
return new Promise(resolve => {
firebase.auth().onAuthStateChanged(user => {
_currentUser = user
return resolve(user)
})
})
}
type AdditionalInfo = {
id: string,
createdAt: number,
updatedAt: number
}
class Store<T> {
_ref: any;
_refPath: string;
constructor (refPath: string) {
this._refPath = refPath
this._ref = firebase.database().ref(this._refPath)
}
getRef () {
return this._ref
}
async insert (item: T): Promise<string> {
const {key} = this._ref.push({})
const now = Date.now()
const data = Object.assign({}, item, {id: key, createdAt: now, updatedAt: now})
await this._ref.child(key).set(data)
return data
}
async update (subset: $Subtype<T> & {id: string}) {
const item = await this.find(subset.id)
return this._ref.child(subset.id).set(Object.assign({}, item, subset))
}
replace (item: T & AdditionalInfo) {
return this._ref.child(item.id).set(Object.assign({}, item, {updatedAt: Date.now()}))
}
async find (id: string): Promise<T & AdditionalInfo> {
const snapshot = await this._ref.child(id).once('value')
return snapshot.val()
}
async all (): Promise<Array<T & AdditionalInfo>> {
const snapshot = await this._ref.once('value')
return snapshot.val()
}
async clear (confirmed: boolean): Promise<void> {
if (confirmed) {
await this._ref.remove()
}
}
observeAll (): Observable<Array<T & AdditionalInfo>> {
return new Observable(observer => {
this._ref.on('value', snapshot => {
observer.next(snapshot.val())
})
return () => {}
})
}
observeOne (id: string): Observable<T & AdditionalInfo> {
const childRef = this._ref.child(id)
return new Observable(observer => {
childRef.on('value', snapshot => {
observer.next(snapshot.val())
})
return () => {}
})
}
}
export type Todo = {
title: string,
done: boolean
}
// run
;(async () => {
const currentUser = await getCurrentUser()
const todoStore: Store<Todo> = new Store(`todos/${currentUser.uid}`)
todoStore.observeAll().subscribe(items => {
console.log('all', items)
})
// await todoStore.clear(true)
const saved = await todoStore.insert({
title: 'Eat meal',
done: false
})
console.log(saved)
// await todoStore.replace({...saved, done: true})
await todoStore.update(Object.assign({}, saved, {
done: true
}))
const todo = await todoStore.find(saved.id)
console.log(todo)
const all = await todoStore.all()
console.log(all)
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment