Skip to content

Instantly share code, notes, and snippets.

@ight-reco
Last active October 18, 2019 04:33
Show Gist options
  • Save ight-reco/46d7d0a3902e0979857be143305a454e to your computer and use it in GitHub Desktop.
Save ight-reco/46d7d0a3902e0979857be143305a454e to your computer and use it in GitHub Desktop.
Example to use vuex-module-decorators and Vuexfire
import { Module, VuexModule, Action } from 'vuex-module-decorators'
import firebase from '~/modules/firebase'
import { FirestoreAction, FirestoreActionContext } from '~/modules/vuexfire-decorator'
const firestore = firebase.firestore()
export interface FirestoreState {
user: User | null
}
@Module({ stateFactory: true, namespaced: true, name: 'firestore' })
export default class FirestoreModule extends VuexModule implements FirestoreState {
user: User | null = null
@Action({ rawError: true })
@FirestoreAction()
init(firebaseUser: firebase.User) {
// Refactor: this line is kind of danger, so it should be refactored
const { bindFirestoreRef } = this.context as FirestoreActionContext<any, any>
return bindFirestoreRef('user', firestore.doc(`users/${firebaseUser.uid}`))
}
}
import { Module, VuexModule, Action } from 'vuex-module-decorators'
import firebase from '~/modules/firebase'
import { firestoreAction } from 'vuexfire'
const firestore = firebase.firestore()
export interface FirestoreState {
user: User | null
}
@Module({ stateFactory: true, namespaced: true, name: 'firestore' })
export default class FirestoreModule extends VuexModule implements FirestoreState {
user: User | null = null
@Action({ rawError: true })
init(firebaseUser: firebase.User) {
const action = firestoreAction(({ bindFirestoreRef }) => {
return bindFirestoreRef('user', firestore.doc(`users/${firebaseUser.uid}`))
}) as Function
// Call function that firebaseAction returns
return action(this.context)
}
}
import { Store } from 'vuex'
import { vuexfireMutations } from 'vuexfire'
import { initialiseStores } from '~/modules/store-accessor'
const initializer = (store: Store<any>) => initialiseStores(store)
export const plugins = [initializer]
// Vuexfire mutations should be in root
export const mutations = { ...vuexfireMutations }
export * from '~/utils/store-accessor'
<template>
<div>{{ user }}</div>
</template>
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import { firestoreStore } from '~/store'
import firebase from '~/firebase/
@Component
export default class Index extends Vue {
mounted() {
firebase.auth().onAuthStateChanged((firebaseUser) => {
if (firebaseUser) {
firestoreStore.init(firebaseUser)
}
}
}
get user() {
return firestoreStore.user
}
}
</script>
import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import ThemeModule from '~/store/theme'
import FirestoreModule from '~/store/firestore'
// eslint-disable-next-line import/no-mutable-exports
let firestoreStore: FirestoreModule
function initialiseStores(store: Store<any>): void {
firestoreStore = getModule(FirestoreModule, store)
}
export { initialiseStores, firestoreStore }
import { firestore } from 'firebase'
import { ActionContext } from 'vuex'
import { FirestoreOptions } from '@posva/vuefire-core'
import { firestoreAction } from 'vuexfire'
// FirestoreActionContext wasn't exported, so forked it
// cf. https://github.com/vuejs/vuefire/blob/f90470babb2a10574a561c3d2924a6f8435c089d/packages/vuexfire/src/firestore.ts
export interface FirestoreActionContext<S, R> extends ActionContext<S, R> {
bindFirestoreRef(
key: string,
ref: firestore.Query | firestore.CollectionReference,
options?: FirestoreOptions
): Promise<firestore.DocumentData[]>
bindFirestoreRef(
key: string,
ref: firestore.DocumentReference,
options?: FirestoreOptions
): Promise<firestore.DocumentData>
unbindFirestoreRef(key: string): void
}
export function FirestoreAction() {
return function(_target: any, _key: string, descriptor: PropertyDescriptor) {
const delegate: Function = descriptor.value
descriptor.value = function(payload: any) {
const action = firestoreAction((context) => {
const thisObj = { context }
return delegate.call(thisObj, payload)
}) as Function
// @ts-ignore
return action(this.context)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment