firex-store

If you use this npm, you can read or write firestore data, easily
- It is inspired by vuexfire
Installation
npm install --save firex-store
Example
others comming soon
Important
-
Return values or state values bound to Firestore has docId
(documentId in Firestore) property.
-
A store module cannot subscribe to more than one 'collection' and 'document'
-
If you'd like to subscribe again after unsubscribing 'collection', set the property of the store you'd like to subscribe to []
and then subscribe.
Usage
Before Start...
- You have to initailize firebase
.....
firebase.initializeApp({
apiKey: [your firebase api key],
projectId: [your project id],
.....
})
export const firestore = firebase.firestore()
Import Path
import { } from 'firex-store'
1. Subscribe Firestore, using firex-store actions
-
method: firestoreMutations
-
parameters:
- type: 'document' | 'collection' | 'all'
- all: 'document' and 'collection'
-
method: firestoreSubscribeAction
-
parameters:
- firestoreSubscriber: FirestoreSubscriber instance
- options?:
- actionName: string | undefined
- see Options
-
class: FirestoreSubscriber
-
class methods:
- from: Make instance
- parameter:
- ref: firebase.firestore.DocumentReference | firebase.firestore.CollectionReference | firebase.firestore.Query
- return:
- bindTo: Bind subscribe data to state property
- parameter:
- statePropName: string. state property
- return:
Ex. Subscribe collection and document
part1. Set Store
import { firestoreMutations, firestoreSubscribeAction, FirestoreSubscriber } from 'firex-store'
export default {
namespaced: true,
state: {
comments: [],
comment: null
},
mutations: {
...firestoreMutations('collection'),
...firestoreMutations('document')
},
actions: {
...firestoreSubscribeAction(
FirestoreSubscriber
.from(firebase.firestore().collection('/comments'))
.bindTo('comments')
),
...firestoreSubscribeAction(
FirestoreSubscriber
.from(firebase.firestore().collection('/comments').doc('commentId'))
.bindTo('comment'),
{ actionName: 'subscribeComment' }
),
}
.....
}
part2. Call action
<script>
import { actionTypes } from 'firex-store'
export default {
name: 'Comments',
created() {
this.$store.dispatch(`comment/${actionTypes.collection.SUBSCRIBE}`)
this.$store.dispatch(`comment/subscribeComment`)
}
}
</script>
2. Subscribe Firestore, using custom actions
Ex. Subscribe collection
part1. Set Store
import { firestoreMutations, firestoreSubscribeAction, FirestoreSubscriber } from 'firex-store'
export default {
namespaced: true,
state: {
comments: []
},
mutations: {
...firestoreMutations('collection')
},
actions: {
subscribeAll: ({ state, commit }) => {
FirestoreSubscriber
.from(firebase.firestore().collection('/comments'))
.bindTo('comments')
.subscribe(state, commit)
}
}
.....
}
part2. Call action
<script>
export default {
name: 'Comments',
created() {
this.$store.dispatch(`user/subscribeAll`)
}
}
</script>
3. Unsubscribe Firestore, using firex-store actions
Ex. Unsubscribe collection
part1. Set Store
import { firestoreMutations, firestoreSubscribeAction, firestoreUnsubscribeAction, FirestoreSubscriber, FirestoreUnsubscriber } from 'firex-store'
export default {
namespaced: true,
state: {
comments: [],
comment: null
},
mutations: {
...firestoreMutations('all')
},
actions: {
...firestoreSubscribeAction(
FirestoreSubscriber
.from(firebase.firestore().collection('/comments'))
.bindTo('comments')
)
...firestoreSubscribeAction(
FirestoreSubscriber
.from(firebase.firestore().collection('/comments').doc('commentId'))
.bindTo('comment')
)
...firestoreUnsubscribeAction(
FirestoreUnsubscriber
.on('comments'),
{ type: 'collection' }
)
...firestoreUnsubscribeAction(
FirestoreUnsubscriber
.on('comment'),
{ type: 'document' }
)
}
.....
}
part2. Call action
<script>
import { actionTypes } from 'firex-store'
export default {
name: 'Comments',
created() {
this.$store.dispatch(`comment/${actionTypes.collection.SUBSCRIBE}`)
this.$store.dispatch(`comment/${actionTypes.document.SUBSCRIBE}`)
this.$store.dispatch(`comment/${actionTypes.collection.UNSUBSCRIBE}`)
this.$store.dispatch(`comment/${actionTypes.document.UNSUBSCRIBE}`)
}
}
</script>
4. Unsubscribe Firestore, using custom actions
- class
FirestoreUnsubscriber
- class method:
- on: Make FirestoreUnsubscriber instance
- parameter:
- statePropName: string. state property
- return:
- unsubscribe:
import { firestoreMutations, firestoreSubscribeAction, FirestoreSubscriber, FirestoreUnsubscriber } from 'firex-store'
export default {
namespaced: true,
state: {
comments: []
},
mutations: {
...firestoreMutations('collection')
},
actions: {
subscribeAll: ({ state, commit }) => {
FirestoreSubscriber
.from(firebase.firestore().collection('/comments'))
.bindTo('comments')
.subscribe(state, commit)
},
unsubscribeAll: ({ state }) => {
FirestoreUnsubscriber
.on('comments')
.unsubscribe(state)
}
}
.....
}
part2. Call action
<script>
export default {
name: 'Comments',
created() {
this.$store.dispatch(`user/subscribeAll`)
this.$store.dispatch(`user/unsubscribeAll`)
}
}
</script>
5. Fetch at once
- class:
FirestoreFinder
- class methods:
- from: Make instance
- parameter:
- ref: firebase.firestore.DocumentReference | firebase.firestore.CollectionReference | firebase.firestore.Query
- return:
- find: fetch firestore data at once
EX. Call in Store Action, to fetch collection
import { FirestoreFinder } from 'firex-store'
export default {
namespaced: true,
state: {},
getters: {},
mutations: {},
actions: {
fetchComments: async ({ commit }) => {
const mapComment = (data) => ({ message: data.message, user: { firstName: data.user.first_name, familyName: data.user.family_name } })
const ref = firestore.collection('/comments')
const result = await FirestoreFinder
.from(ref)
.find({ mapper: mapComment })
commit(***, result)
}
}
}
6. Add to firestore
- class:
FirestoreAdder
- class methods:
- to: Make instance
- parameter:
- ref: firebase.firestore.CollectionReference
- return:
- add: add data to firestore
- data: data you wanna add to firestore
- parameter:
Ex.
import { FirestoreAdder } from 'firex-store'
export default {
namespaced: true,
state: {},
getters: {},
mutations: {},
actions: {
add: async (_, { data }) => {
const result = await FirestoreAdder.to(
firestore.collection('comments')
).add(data, { mapper, errorHandler, completionHandler })
if (typeof result !== 'string') {
}
}
}
}
7. Set to firestore
- class:
FirestoreSetter
- class methods:
- to: Make instance
- parameter:
- ref: firebase.firestore.DocumentReference
- return:
- transaction: Call this if you wanna use transaction
UseCase
: Call this if you wouldn't like to overwrite data- return:
- set: set data to firestore
- data: data you wanna set to firestore
- parameter:
Ex.
import { FirestoreSetter } from 'firex-store'
export default {
namespaced: true,
state: {},
getters: {},
mutations: {},
actions: {
set: async (_, { data }) => {
const result = await FirestoreSetter.to(
firestore.collection('comments').doc('commentId')
)
.set(data, { mapper, errorHandler, completionHandler })
if (typeof result !== 'undefined') {
}
}
}
}
8. MergeSet to firestore (like Update)
- class:
FirestoreMergeSetter
- class methods:
- to: Make instance
- parameter:
- ref: firebase.firestore.DocumentReference
- return:
- transaction: Call this if you wanna use transaction
UseCase
: Call this if you would like to overwrite data or add property to data- return:
- mergeSet: set data to firestore
- data: data you wanna mergeSet to firestore
- parameter:
Ex.
import { FirestoreMergeSetter } from 'firex-store'
export default {
namespaced: true,
state: {},
getters: {},
mutations: {},
actions: {
mergeSet: async (_, { data }) => {
const result = await FirestoreSetter.to(
firestore.collection('comments').doc('commentId')
)
.mergeSet(data, { mapper, errorHandler, completionHandler })
if (typeof result !== 'undefined') {
}
}
}
}
9. Helpers
from and FirestoreReaderServiceFactory
-
from
: Method, factory of FirestoreSubscriber and FirestoreFinder
- parameter:
- ref: firebase.firestore.DocumentReference | firebase.firestore.CollectionReference | firebase.firestore.Query
- return: FirestoreReaderServiceFactory
-
FirestoreReaderServiceFactory
: Class, factory of FirestoreSubscriber and FirestoreFinder
-
parameter:
- ref: firebase.firestore.DocumentReference | firebase.firestore.CollectionReference | firebase.firestore.Query
-
methods:
Ex.
import { firestoreMutations, from } from 'firex-store'
export default {
namespaced: true,
state: {
comments: []
},
mutations: {
...firestoreMutations('collection')
},
actions: {
subscribeAll: ({ state, commit }) => {
from(firebase.firestore().collection('/comments'))
.bindTo('comments')
.subscribe(state, commit)
},
find: () => {
return from(firebase.firestore().collection('/comments').doc('commentId'))
.once()
.find()
}
}
.....
}
on
Ex.
import { firestoreMutations, from, on, firestoreUnsubscriber } from 'firex-store'
export default {
namespaced: true,
state: {
comments: [],
comment: null
},
mutations: {
...firestoreMutations('collection')
},
actions: {
subscribeAll: ({ state, commit }) => {
from(firebase.firestore().collection('/comments'))
.bindTo('comments')
.subscribe(state, commit)
},
find: () => {
return from(firebase.firestore().collection('/comments').doc('commentId'))
.once()
.find()
},
unsubscribe: ({ state }) => {
on('comments').unsubscribe(state)
},
...firestoreUnsubscriber(
on('comment'),
{ type: 'document' }
)
}
.....
}
to and FirestoreDocumentWriterFacade
-
to
: Method, return FirestoreAdder or FirestoreDocumentWriterFacade instance.
- parameter:
- ref: firebase.firestore.DocumentReference | firebase.firestore.CollectionReference
- return: FirestoreAdder or FirestoreDocumentWriterFacade
-
FirestoreDocumentWriterFacade
: Class, facade of FirestoreSetter and FirestoreMergeSetter
-
parameter:
- ref: firebase.firestore.DocumentReference
-
methods:
-
transaction
: call this if you wanna transaction
- return:
- FirestoreDocumentWriterFacade
-
set
: set data to firestore
- data: data you wanna set to firestore
- parameter:
-
mergeSet
: set data to firestore
- data: data you wanna mergeSet to firestore
- parameter:
Ex.
import { to } from 'firex-store'
export default {
namespaced: true,
state: {},
mutations: {},
actions: {
set: async ({ dispatch }, { data }) => {
await to(firestore.colleciton('comments').doc('commentId'))
.set(data)
},
mergeSet: async ({ dispatch }, { data }) => {
const errorHandler = (error) => {
dispatch(`error/OCCURED`, error, { root: true })
console.error(error)
return error
}
await to(firestore.colleciton('comments').doc('commentId'))
.transaction()
.mergeSet(data)
},
add: async ({ dispatch }, { data }) => {
const result = await to(firestore.colleciton('comments')).add(data)
if (typeof result === 'string') {
console.log(`documentId is ${result}`)
} else {
dispatch(`error/OCCURED`, result, { root: true })
}
},
}
.....
}
Options
-
Options
-
mapper:
- Map to something.
Subscribe case
: State prop bound to Firestore or return values map to something if mapper definedSet or add case
: Data which set or added to firestore map to something if mapper defined
-
errorHandler
- If it defined, call it when error occured. But if not, call
console.error(error)
and return error
-
completionHandler
- If it defined, call it when completed
-
afterMutationCalled
FirestoreSubscriber
and firestoreSubscribeAction
only.- If it defined, call it when completed
- This method called after mutation called
- parameters
- payload
- type payload = {
- data: { docId: string | null, [key: string]: any }, <-- subscribed data
- isLast: boolean, <-- In 'document' subscribed , it undefined. In 'collection' subscribed, true or false.
- UseCase: disappear and appear loading bar when subscribed 'collection' data at first
- statePropName: string <-- state property bound to subscribe data
- [key: string]: any }
-
notFoundHandler
FirestoreSubscriber
and firestoreSubscribeAction
only.- If it defined, call it when snapshot doesn't exist
- parameters
- type: 'document' | 'collection'
- isAll:
- undefined when subscribe Document data
- true when subscribe Collection data
- false when subscribe Collection data and document in Collection is not existed
Ex.
const mapUser = (data) => ({
id: data.id
name: data.name
.....
})
const errorHandler = (error) => {
console.error(`[App Name]: ${error}`)
}
const completionHandler = () => {
console.log('completed!')
}
const afterMutationCalled = (payload) => {
if (payload.isLast === false) {
commit('SET_LOADING', true)
} else if (payload.isLast === true) {
commit('SET_LOADING', false)
}
}
const notFoundHandler = (type, isAll) => {
console.log('not found')
}
import { firestoreMutations, from, to } from 'firex-store'
export default {
namespaced: true,
state: {
comments: [],
comment: null,
isLoading: false
},
mutations: {
...firestoreMutations('collection'),
SET_LOADING(state, isLoading) {
state.isLoading = isLoading
}
},
actions: {
subscribe: ({ state, commit }) => {
from(firestore.collection('/comments'))
.bindTo('comments')
.subscribe(state, commit, {
mapper: mapUser,
errorHandler,
completionHandler,
afterMutationCalled,
notFoundHandler
})
},
add: async (_, { data }) => {
await to(firestore.collection('/comments'))
.add(data, { mapper, errorHandler, completionHandler })
}
}
.....
}
Difference from v0
v0 Usage