Skip to content

Commit 2c65180

Browse files
committed
Implementation of query watchers
1 parent acad649 commit 2c65180

20 files changed

Lines changed: 223 additions & 133 deletions

File tree

README.md

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This project was bootstrapped with [nwb](https://github.com/insin/nwb)
44

5-
Firekit was created to help working with Firebase in React Projects that use Redux as state storage.
5+
Firekit was created to help working with Firebase in React Projects that use Redux as state storage.
66

77
You can find a full functional **DEMO** project (React Most Wanted) with source code [here](https://www.react-most-wanted.com/).
88

@@ -15,7 +15,7 @@ You can find a full functional **DEMO** project (React Most Wanted) with source
1515
- [Usage](#usage)
1616
- [Accessing firebaseApp](#accessing-firebaseapp)
1717
- [Connection](#connection)
18-
- [Lists](#lists)
18+
- [Lists and Queries](#lists-and-queires)
1919
- [Paths](#paths)
2020
- [FireForm](#fireform)
2121
- [TO DO](#to-do)
@@ -26,7 +26,7 @@ You can find a full functional **DEMO** project (React Most Wanted) with source
2626
Firekit allows you to watch firebase data and sync it to your redux store with a minimum of code to write. It uses a `Provider` to server the `firebaseApp` to all Components that need it.
2727

2828
Some features that are unque to this firebase toolkit are:
29-
* **persistant watchers** - the watchers are persistant and are not linked to components. You deside when to watch a value in your firebase database and when to unwatch (turn off listeners) it.
29+
* **persistant watchers** - the watchers are persistant and are not linked to components. You deside when to watch a value in your firebase database and when to unwatch (turn off listeners) it.
3030

3131
* **your create firebaseApp** - you initialise the firebaseApp how you want and add it as prop to the firekit `FirebaseProvider` and all your components have access to the firebaseApp
3232

@@ -36,7 +36,7 @@ Some features that are unque to this firebase toolkit are:
3636

3737
* **native firebase** - you can use firebases native sdk for the web. Firekit is just listening on changes. Every change on the data you can make as it is described in the official firebase documentation
3838

39-
* **realtime forms** - firekit has a special Warapper for `redux-forms` witch allows to sync them with the realtime database very simple and plus it is automaticaly synced on field changes in real time if they ocure while your are in the Form
39+
* **realtime forms** - firekit has a special Warapper for `redux-forms` witch allows to sync them with the realtime database very simple and plus it is automaticaly synced on field changes in real time if they ocure while your are in the Form
4040

4141
Features like populating values in the database are omited with purpose. The firebase `cloud functions` are the place where you should populate data that must be saved in multiple places.
4242

@@ -110,46 +110,41 @@ import dialogs from './dialogs/reducer';
110110
import messaging from './messaging/reducer';
111111
import locale from './locale/reducer';
112112
import theme from './theme/reducer';
113-
import {
114-
connectionReducer,
115-
listsReducer,
116-
pathsReducer,
117-
initializationReducer
118-
} from 'firekit'; //Import the reducers
113+
import firekitReducers from 'firekit'; //Import the firekitReducers
114+
115+
116+
console.log(firekitReducers);
119117

120118
const reducers = combineReducers({
121119
browser: responsiveStateReducer,
122120
responsiveDrawer,
123121
form: formReducer,
124122
auth,
125-
initialization: initializationReducer, //Add the initialisation reducer
126-
connection: connectionReducer, //Add the connection reducer
127-
lists: listsReducer, //Add the lists reducer
128-
paths: pathsReducer, //Add the paths reducer
129123
dialogs,
130124
messaging,
131125
locale,
132126
theme,
127+
...firekitReducers //Spread the firekit reducers
133128
})
134129

135130
export default reducers;
136131

137132
```
138-
In future versions the reducers will be combined in a single object that will be reducable.
133+
To add all firekti reducers to your redux store just spread the firekitReducers object into your `comineReducers` object.
139134

140135
**WARNING:** if you are using persistance take care that the reducer `initialization` is not persisted! He saves the watchers. If he would be persisted the watcher would not initialize again after a page reload. If you are using `redux-persist` just add him to the black list.
141136

142137
```js
143138
persistStore(store, {blacklist:['auth', 'form', 'connection', 'initialization'] }, ()=>{}); //Add initialization to persistance blacklist if you use persistance
144139
```
145140

146-
**INFO:** the reducers are not customasable so they have to use the names as they are here in the snipped. In future we could add customatisation for this so they could have any name you want.
141+
**INFO:** the reducers are not customasable. In future we could add customatisation for this so they could have any name you want.
147142

148143
## Usage
149144

150145
Let us now do something with our firekit :smile:
151-
To use `firekit` in a component we need to tell the component to get all `firekit` props from the context.
152-
We use for that a simple call `withFirebase`. It is very similar to the `react-router` call `withRouter`. The usage is exactly the same.
146+
To use `firekit` in a component we need to tell the component to get all `firekit` props from the context.
147+
We use for that a simple call `withFirebase`. It is very similar to the `react-router` call `withRouter`. The usage is exactly the same.
153148

154149
Let us take a look on a simple component.
155150

@@ -247,7 +242,7 @@ class MyComponent extends Component {
247242
const { initConnection }= this.props;
248243
initConnection(); //Here we started watching the connection state
249244
}
250-
245+
251246
componentWillUnmount() {
252247
const { unsubscribeConnection, }= this.props;
253248
unsubscribeConnection(); // Here we unsunscribe the listening to the connection state
@@ -276,9 +271,9 @@ export default connect(
276271
)(withFirebase(MyComponent));
277272
```
278273

279-
### Lists
274+
### Lists and Queries
280275

281-
We can easely observe lists in the realtime database using the `watchList` and `unwatchList` API calls.
276+
We can easely observe lists in the realtime database using the `watchList` and `unwatchList` API calls. The same calls are used to observe Firebase queries. `watchList` and `unwatchList` can recieve as parameter a string to a database path or a Firebase reference to that path. If you have a simple reference to a path using just the string of the path is the right choice. But if you have a Firebase query reference you can send that reference with all its query calls as parameter.
282277

283278
```js
284279
import React, { Component } from 'react';
@@ -289,18 +284,25 @@ import _ from 'lodash';
289284
class MyComponent extends Component {
290285

291286
componentDidMount(){
292-
const { watchList }= this.props;
293-
watchList('users'); //Here we started watching the list
287+
const { watchList, firebaseApp }= this.props;
288+
289+
watchList('users'); //Here we started watching the users list
290+
291+
//Her we watch a simple firebase query
292+
let tasksRef= firebaseApp.database().ref('tasks').limitToFirst(10);
293+
watchList(tasksRef);
294+
294295
}
295-
296+
296297
componentWillUnmount() {
297298
const { unwatchList, }= this.props;
298299
unwatchList('users'); // We can unwatch the list on unmounting the Component
300+
unwatchList('tasks'); // To unwatch a query qe can use just the ref path string
299301
}
300-
302+
301303
rednerList = () => {
302304
const {users} =this.props;
303-
305+
304306
if(users===undefined){
305307
return <div></div>
306308
}
@@ -336,9 +338,9 @@ export default connect(
336338
)(withFirebase(MyComponent));
337339
```
338340

339-
Here we unwatched the list on `componentWillUnmount`. We could also leave this away and the list will change in realtime in the background and it will not load all data on revisiting the Component again.
341+
Here we unwatched the list on `componentWillUnmount`. We could also leave this away and the list will change in realtime in the background and it will not load all data on revisiting the Component again.
340342

341-
If you are using persistand watcher you would have to unwatch them in some point of your application or on application exit.
343+
If you are using persistand watcher you would have to unwatch them in some point of your application or on application exit.
342344
Because of that there are special calls that allow us to unwatch all persistand watcher in a single call. That could be calles in the root component of your application like this:
343345

344346
```js
@@ -351,7 +353,7 @@ Because of that there are special calls that allow us to unwatch all persistand
351353
unwatchAllLists();
352354
unwatchAllPaths();
353355
}
354-
356+
355357
//... other code of your root Component
356358

357359
```
@@ -370,12 +372,12 @@ The paths watcher exactly like the lists watcher with `watchPath` and `unwatchPa
370372
const { watchPath }= this.props;
371373
watchPath('users_count'); //Here we started watching the path
372374
}
373-
375+
374376
componentWillUnmount() {
375377
const { unwatchPath, }= this.props;
376378
unwatchPath('users'); // We can unwatch the path on unmounting the Component
377379
}
378-
380+
379381
//...
380382
```
381383

@@ -395,15 +397,15 @@ And comes the cool thing. If you are in the Form working on fields and someone e
395397

396398
//...
397399

398-
<FireForm
399-
name={'companie'}
400-
path={`${path}`}
401-
onSubmitSuccess={(values)=>{history.push('/companies');}}
402-
onDelete={(values)=>{history.push('/companies');}}
403-
handleCreateValues={this.handleCreateValues}
404-
uid={match.params.uid}>
405-
<Form /> // Here is your simple form
406-
</FireForm>
400+
<FireForm
401+
name={'companie'}
402+
path={`${path}`}
403+
onSubmitSuccess={(values)=>{history.push('/companies');}}
404+
onDelete={(values)=>{history.push('/companies');}}
405+
handleCreateValues={this.handleCreateValues}
406+
uid={match.params.uid}>
407+
<Form /> // Here is your simple form
408+
</FireForm>
407409

408410
//...
409411

@@ -412,11 +414,11 @@ And comes the cool thing. If you are in the Form working on fields and someone e
412414

413415
## TO DO
414416

415-
- [ ] compine all reducer to one import
417+
- [X] compine all reducer to one import
416418
- [ ] integrate selectors
417419
- [ ] integrate firebase messaging
418420
- [ ] integrate firebase auth watcher
419-
- [ ] integrate firebase queries watcher
421+
- [X] integrate firebase queries watcher
420422

421423
## License
422424

demo/src/components/containers/About/About.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { Component } from 'react';
22
import {injectIntl, intlShape} from 'react-intl';
33
import { Activity } from '../../containers/Activity';
4-
import { withFirebase } from 'firekit';
4+
import { withFirebase } from '../../src';
55

66
class About extends Component {
77

demo/src/components/containers/Activity/Activity.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
darkWhite,
1616
} from 'material-ui/styles/colors';
1717
import config from '../../config';
18-
import { withFirebase } from 'firekit';
18+
import { withFirebase } from '../../src';
1919

2020
export class Activity extends Component {
2121

demo/src/components/containers/Companies/Companies.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import FontIcon from 'material-ui/FontIcon';
1111
import FloatingActionButton from 'material-ui/FloatingActionButton';
1212
import {withRouter} from 'react-router-dom';
1313
import Avatar from 'material-ui/Avatar';
14-
import { withFirebase } from 'firekit';
14+
import { withFirebase } from '../../src';
1515

1616
class Vehicles extends Component {
1717

demo/src/components/containers/Tasks/Task.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import firebase from 'firebase';
1111
import FontIcon from 'material-ui/FontIcon';
1212
import FlatButton from 'material-ui/FlatButton';
1313
import Dialog from 'material-ui/Dialog';
14-
import { withFirebase } from 'firekit';
14+
import { withFirebase } from '../../src';
1515

1616
const path='/public_tasks/';
1717

demo/src/components/containers/Tasks/Tasks.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {BottomNavigation} from 'material-ui/BottomNavigation';
1919
import {withRouter} from 'react-router-dom';
2020
import FlatButton from 'material-ui/FlatButton';
2121
import Dialog from 'material-ui/Dialog';
22-
import { withFirebase } from 'firekit';
22+
import { withFirebase } from '../../src';
2323

2424
class Tasks extends Component {
2525

demo/src/components/containers/Users/Users.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Avatar from 'material-ui/Avatar';
1111
import FontIcon from 'material-ui/FontIcon';
1212
import {GoogleIcon, FacebookIcon, GitHubIcon, TwitterIcon} from '../../components/Icons';
1313
import IconButton from 'material-ui/IconButton';
14-
import { withFirebase } from 'firekit';
14+
import { withFirebase } from '../../src';
1515

1616
class Users extends Component {
1717

demo/src/containers/About/About.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { Component } from 'react';
22
import {injectIntl, intlShape} from 'react-intl';
33
import { Activity } from '../../containers/Activity';
4-
import { withFirebase } from 'firekit';
4+
import { withFirebase } from '../../../../src';
55

66
class About extends Component {
77

demo/src/containers/Activity/Activity.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
darkWhite,
1616
} from 'material-ui/styles/colors';
1717
import config from '../../config';
18-
import { withFirebase } from 'firekit';
18+
import { withFirebase } from '../../../../src';
1919

2020
export class Activity extends Component {
2121

demo/src/containers/Companies/Companie.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import firebase from 'firebase';
1010
import FontIcon from 'material-ui/FontIcon';
1111
import FlatButton from 'material-ui/FlatButton';
1212
import Dialog from 'material-ui/Dialog';
13-
import { firebaseDb } from '../../firebase';
13+
import { withFirebase } from '../../../../src';
1414

1515
const path='/companies/';
1616

@@ -43,11 +43,11 @@ class Companie extends Component {
4343

4444
handleDelete = () => {
4545

46-
const {history, match}=this.props;
46+
const {history, match, firebaseApp}=this.props;
4747
const uid=match.params.uid;
4848

4949
if(uid){
50-
firebaseDb.ref().child(`${path}${uid}`).remove().then(()=>{
50+
firebaseApp.database().ref().child(`${path}${uid}`).remove().then(()=>{
5151
this.handleClose();
5252
history.goBack();
5353
})
@@ -122,4 +122,4 @@ const mapStateToProps = (state) => {
122122

123123
export default connect(
124124
mapStateToProps, {setDialogIsOpen}
125-
)(injectIntl(withRouter(Companie)));
125+
)(injectIntl(withRouter(withFirebase(Companie))));

0 commit comments

Comments
 (0)