Skip to content

Commit 6f0d646

Browse files
authored
v2.2.0-alpha
* fix(profile): profile update on login works with email login (used to require `createUser`) - prescottprue#475 * feat(HOCs): optimize firestoreConnect unset / set listeners - @demoran23 * fix(auth): move detaching of profile listeners before `signOut` within `logout` method to fix `permission_denied` errors - prescottprue#494 * fix(enhancer): support config already existing on store - [132 of redux-firestore](prescottprue/redux-firestore#132)
2 parents 18e512f + 7b5e4c1 commit 6f0d646

File tree

6 files changed

+223
-25
lines changed

6 files changed

+223
-25
lines changed

.travis.yml

+11-7
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,35 @@ language: node_js
55
node_js:
66
- 6 # Maintenance
77
- 8 # Active
8-
- 10 # Current release
8+
- 10
99

1010
notifications:
11-
# Only send notifications when travis status changes
1211
email:
12+
# Only send notifications when travis status changes
1313
on_failure: change
1414
on_success: change
1515

16-
addons:
17-
code_climate:
18-
repo_token: $CODE_CLIMATE
19-
2016
cache:
17+
bundler: true
2118
directories:
22-
- node_modules
19+
- $HOME/.npm
2320

2421
branches:
2522
only:
2623
- master
2724
- next
2825

26+
install:
27+
- npm i
28+
2929
script:
3030
- npm run lint
3131
- npm run test:cov
3232

33+
addons:
34+
code_climate:
35+
repo_token: $CODE_CLIMATE
36+
3337
deploy:
3438
- provider: npm
3539
skip_cleanup: true

package-lock.json

+164-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-redux-firebase",
3-
"version": "2.1.7",
3+
"version": "2.2.0-alpha",
44
"description": "Redux integration for Firebase. Comes with a Higher Order Components for use with React.",
55
"main": "lib/index.js",
66
"module": "es/index.js",
@@ -22,6 +22,7 @@
2222
"build:size": "cross-env SIZE=true BABEL_ENV=commonjs NODE_ENV=production webpack src/index.js dist/react-redux-firebase.min.js",
2323
"build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
2424
"watch": "npm run build:commonjs -- --watch",
25+
"watch:es": "npm run build:es -- --watch",
2526
"prepare": "npm run clean && npm run build",
2627
"prepush": "npm run lint",
2728
"docs:clean": "rimraf _book",

src/actions/auth.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,11 @@ export const login = (dispatch, firebase, credentials) => {
535535
* @param {Object} firebase - Internal firebase object
536536
* @private
537537
*/
538-
export const logout = (dispatch, firebase) =>
539-
firebase
538+
export const logout = (dispatch, firebase) => {
539+
// detach profile listener before logging out to prevent permission_denied
540+
// errors (for more info see #494)
541+
unWatchUserProfile(firebase)
542+
return firebase
540543
.auth()
541544
.signOut()
542545
.then(() => {
@@ -545,9 +548,9 @@ export const logout = (dispatch, firebase) =>
545548
preserve: firebase._.config.preserveOnLogout
546549
})
547550
firebase._.authUid = null
548-
unWatchUserProfile(firebase)
549551
return firebase
550552
})
553+
}
551554

552555
/**
553556
* @description Create a new user in auth and add an account to userProfile root

src/enhancer.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,26 @@ export default (instance, otherConfig) => next => (
107107
)
108108
}
109109

110-
const configs = { ...defaultConfig, ...otherConfig }
110+
// Support existing _ config (i.e. reduxFirestore before)
111+
const existingConfig = (instance && instance._) || {}
112+
113+
// Combine all configs
114+
const configs = { ...existingConfig, ...defaultConfig, ...otherConfig }
115+
116+
// Create firebase instance with config and dispatch
111117
firebaseInstance = createFirebaseInstance(
112118
instance.firebase_ || instance,
113119
configs,
114120
store.dispatch
115121
)
116122

123+
// Inialize auth (attaches auth state change listener)
117124
authActions.init(store.dispatch, firebaseInstance)
125+
126+
// Attach instance (with methods wrapped in dispatch) to store
118127
store.firebase = firebaseInstance
119128

129+
// Attach firebaseAuthIsReady promise unless disabled through config
120130
if (configs.attachAuthIsReady) {
121131
store.firebaseAuthIsReady = createAuthIsReady(store, configs)
122132
}

src/firestoreConnect.js

+29-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { Component } from 'react'
22
import PropTypes from 'prop-types'
3-
import { isEqual } from 'lodash'
3+
import { isEqual, some, filter } from 'lodash'
44
import hoistStatics from 'hoist-non-react-statics'
55
import { createCallable, wrapDisplayName } from './utils'
66

@@ -35,9 +35,14 @@ export const createFirestoreConnect = (storeKey = 'store') => (
3535
prevData = null
3636
store = this.context[storeKey]
3737

38-
componentWillMount() {
38+
get firestoreIsEnabled() {
3939
const { firebase, firestore } = this.store
40-
if (firebase.firestore && firestore) {
40+
return firebase && firebase.firestore && firestore
41+
}
42+
43+
componentWillMount() {
44+
const { firestore } = this.store
45+
if (this.firestoreIsEnabled) {
4146
// Allow function to be passed
4247
const inputAsFunc = createCallable(dataOrFn)
4348
this.prevData = inputAsFunc(this.props, this.store)
@@ -47,26 +52,38 @@ export const createFirestoreConnect = (storeKey = 'store') => (
4752
}
4853

4954
componentWillUnmount() {
50-
const { firebase, firestore } = this.store
51-
if (firebase.firestore && this.prevData) {
55+
const { firestore } = this.store
56+
if (this.firestoreIsEnabled && this.prevData) {
5257
firestore.unsetListeners(this.prevData)
5358
}
5459
}
5560

5661
componentWillReceiveProps(np) {
57-
const { firebase, firestore } = this.store
62+
const { firestore } = this.store
5863
const inputAsFunc = createCallable(dataOrFn)
5964
const data = inputAsFunc(np, this.store)
60-
// Handle a data parameter having changed
61-
if (firebase.firestore && !isEqual(data, this.prevData)) {
62-
// UnWatch all current events
63-
firestore.unsetListeners(this.prevData)
65+
66+
// Handle changes to data
67+
if (this.firestoreIsEnabled && !isEqual(data, this.prevData)) {
68+
const changes = this.getChanges(data, this.prevData)
69+
6470
this.prevData = data
65-
// Watch new events
66-
firestore.setListeners(data)
71+
72+
// Remove listeners for inactive subscriptions
73+
firestore.unsetListeners(changes.removed)
74+
75+
// Add listeners for new subscriptions
76+
firestore.setListeners(changes.added)
6777
}
6878
}
6979

80+
getChanges(data = [], prevData = []) {
81+
const result = {}
82+
result.added = filter(data, d => !some(prevData, p => isEqual(d, p)))
83+
result.removed = filter(prevData, p => !some(data, d => isEqual(p, d)))
84+
return result
85+
}
86+
7087
render() {
7188
const { firebase, firestore } = this.store
7289
return (

0 commit comments

Comments
 (0)