mobx-firebase-store
MobxFirebaseStore
allows you to subscribe to firebase data via firebase-nest
subscriptions and have the data flow into mobx
observable maps.
See live: storybook
React Component Example
;;;;; const fbApp = firebase; const store = firebase; /* Real-time messages */ { return <div style=border:'1px grey solid' key=messageKey> <div>messageDatatext</div> <div>Posted messageDatatimestamp</div> </div> ; } { const messages = store; //'myMsgs' matches the subKey below //autoSubscriber keeps track of loading and error status when using store.subscribeSubsWithPromise const _autoSubscriberFetching: fetching _autoSubscriberError: fetchError error = thisstate //store.getData returns mobx observable map - use keys(), get(), entries(), etc. to render the data //do NOT use set() or other mutations on the map -- updates should be written directly to firebase, and will get reflected in the observable map automatically. if !messages return <div>Loading messages...</div> return <div> Messages: messages </div> ; } //Subscribe to and observe firebase data subKey: 'myMsgs' //any unique string describing this subscription; must match getData call asList: true //or asValue: true. asList will internally subscribe via firebase child_added/removed/changed; asValue via onValue. path: 'samplechat/messages' //firebase location, //Optional - get data callbacks after store data is already updated: console //can add more than one subscription to this array store;
react-native is supported - libs and usage are the same
Supports Firebase queries - filtering and sorting
subKey: 'myMsgs' asValue: true //have to use asValue if using orderBy* and want to preserve the ordering in the observable map fbRef store;
Supports data transformation
With asValue
sub, define transformValue : (val) => ...
on the sub.
Or with asList
, define transformChild: (val) => ...
.
Supports nested subscriptions
For example, for each message, subscribe to its author (message.uid).
//... subKey: 'myMsgs' asValue: true fbRef subKey: 'user_' + messageDatauid asValue: true fbRef //...
If we have getSubs
defined as above and 2 messages by 2 users, fred
and barney
, the subscription graph can be pictured something like this:
Also can nest subscriptions for specific fields - for example, parent subscription is for a blog, nested subscription is for its author.
{ return subKey: 'blog_'+propsblogKey asValue: true fbRef fieldSubs: subKey: 'user_' + authorKey asValue: true path: 'users/' + authorKey ; }
See chat for examples of how to display the firebase subscription graph.
More examples
chat - includes auth
next.js example - server-side rendering with firebase-admin, firebase and mobx, and auth
react-native-gifted-chat example
Required libs
npm install mobx mobx-react firebase firebase-nest mobx-firebase-store --save
Run examples in storybook
Inspired by react-native-web-starter examples.
cd examples-storybook
orcd examples-storybook-firebase3
To run firebase3 examples, you need to set your API key in index.js. You can create one at https://console.cloud.google.com, credentials->create credentials->API key->browser key.
-
npm install
-
npm run storybook
Features
-
Firebase 3.x is supported (https://github.com/nyura123/mobx-firebase-store/tree/master/examples/listAndDetailFirebase3)
-
Allows to differentiate between data not being subscribed or loaded (
store.getData(...) === undefined
) vs being empty. -
Writes to maps are done inside transactions for better performance.
-
Throttles writes by default - this helps if we want to avoid re-rendering too frequently, such as during initial load of data.
To turn off:
const store = new MobxFirebaseStore(fb, {throttle: {shouldThrottle: false}})
.Throttling params can also be tweaked.
-
firebase-nest
subscriptions allow subscribing to whole graphs of data.For example, via a single subscription, subscribe to
items
and to eachitems
'scategory
. If an item is ever deleted or its category is changed, the nested category subscription is deleted/changed automatically. -
store.subscribeSubsWithPromise
provides a promise that resolves when initial data, including nested/child data, is loaded. -
MobxFirebaseStore
can be extended to optionally implement various callbacks:onData(type, snapshot, sub)
-- be notified on every data update coming in from firebase after it has already been applied to observable maps.onWillSubscribe(sub)
,onWillUnsubscribe(subKey)
-
Exposes
subscribedRegistry
which shows how many subscribers are currently listening to each piece of data. -
store.reset()
can be used to unsubscribe from all data & reset the store (for example on user logout) -
Use
firebase-nest
autoSubscriber
to allow React components to specify their prop- and state-dependent subscriptions and be automatically subscribed/unsubscribed.If your component's props or state is updated, the subscriptions will be updated automatically.
-
firebase-nest
&autoSubscriber
both minimize unnecessary ref.off()/ref.on() flickering. -
By default, data is removed from fbStore cache when it no longer has any subscribers.
-
When subscribing
asList
,onData
with type=FB_INIT_VAL
gets the whole initial list as one update. -
Firebase queries are supported via resolveFirebaseRef function you can set on each sub. Otherwise you can set path:
fbRefor
path: 'yourPath'