Skip to content

Commit

Permalink
v2.2.0-alpha
Browse files Browse the repository at this point in the history
* fix(profile): profile update on login works with email login (used to require `createUser`) - #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 - #494
* fix(enhancer): support config already existing on store - [132 of redux-firestore](prescottprue/redux-firestore#132)
  • Loading branch information
prescottprue committed Aug 13, 2018
2 parents 18e512f + 7b5e4c1 commit 6f0d646
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 25 deletions.
18 changes: 11 additions & 7 deletions .travis.yml
Expand Up @@ -5,31 +5,35 @@ language: node_js
node_js:
- 6 # Maintenance
- 8 # Active
- 10 # Current release
- 10

notifications:
# Only send notifications when travis status changes
email:
# Only send notifications when travis status changes
on_failure: change
on_success: change

addons:
code_climate:
repo_token: $CODE_CLIMATE

cache:
bundler: true
directories:
- node_modules
- $HOME/.npm

branches:
only:
- master
- next

install:
- npm i

script:
- npm run lint
- npm run test:cov

addons:
code_climate:
repo_token: $CODE_CLIMATE

deploy:
- provider: npm
skip_cleanup: true
Expand Down
165 changes: 164 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "react-redux-firebase",
"version": "2.1.7",
"version": "2.2.0-alpha",
"description": "Redux integration for Firebase. Comes with a Higher Order Components for use with React.",
"main": "lib/index.js",
"module": "es/index.js",
Expand All @@ -22,6 +22,7 @@
"build:size": "cross-env SIZE=true BABEL_ENV=commonjs NODE_ENV=production webpack src/index.js dist/react-redux-firebase.min.js",
"build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
"watch": "npm run build:commonjs -- --watch",
"watch:es": "npm run build:es -- --watch",
"prepare": "npm run clean && npm run build",
"prepush": "npm run lint",
"docs:clean": "rimraf _book",
Expand Down
9 changes: 6 additions & 3 deletions src/actions/auth.js
Expand Up @@ -535,8 +535,11 @@ export const login = (dispatch, firebase, credentials) => {
* @param {Object} firebase - Internal firebase object
* @private
*/
export const logout = (dispatch, firebase) =>
firebase
export const logout = (dispatch, firebase) => {
// detach profile listener before logging out to prevent permission_denied
// errors (for more info see #494)
unWatchUserProfile(firebase)
return firebase
.auth()
.signOut()
.then(() => {
Expand All @@ -545,9 +548,9 @@ export const logout = (dispatch, firebase) =>
preserve: firebase._.config.preserveOnLogout
})
firebase._.authUid = null
unWatchUserProfile(firebase)
return firebase
})
}

/**
* @description Create a new user in auth and add an account to userProfile root
Expand Down
12 changes: 11 additions & 1 deletion src/enhancer.js
Expand Up @@ -107,16 +107,26 @@ export default (instance, otherConfig) => next => (
)
}

const configs = { ...defaultConfig, ...otherConfig }
// Support existing _ config (i.e. reduxFirestore before)
const existingConfig = (instance && instance._) || {}

// Combine all configs
const configs = { ...existingConfig, ...defaultConfig, ...otherConfig }

// Create firebase instance with config and dispatch
firebaseInstance = createFirebaseInstance(
instance.firebase_ || instance,
configs,
store.dispatch
)

// Inialize auth (attaches auth state change listener)
authActions.init(store.dispatch, firebaseInstance)

// Attach instance (with methods wrapped in dispatch) to store
store.firebase = firebaseInstance

// Attach firebaseAuthIsReady promise unless disabled through config
if (configs.attachAuthIsReady) {
store.firebaseAuthIsReady = createAuthIsReady(store, configs)
}
Expand Down
41 changes: 29 additions & 12 deletions src/firestoreConnect.js
@@ -1,6 +1,6 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { isEqual } from 'lodash'
import { isEqual, some, filter } from 'lodash'
import hoistStatics from 'hoist-non-react-statics'
import { createCallable, wrapDisplayName } from './utils'

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

componentWillMount() {
get firestoreIsEnabled() {
const { firebase, firestore } = this.store
if (firebase.firestore && firestore) {
return firebase && firebase.firestore && firestore
}

componentWillMount() {
const { firestore } = this.store
if (this.firestoreIsEnabled) {
// Allow function to be passed
const inputAsFunc = createCallable(dataOrFn)
this.prevData = inputAsFunc(this.props, this.store)
Expand All @@ -47,26 +52,38 @@ export const createFirestoreConnect = (storeKey = 'store') => (
}

componentWillUnmount() {
const { firebase, firestore } = this.store
if (firebase.firestore && this.prevData) {
const { firestore } = this.store
if (this.firestoreIsEnabled && this.prevData) {
firestore.unsetListeners(this.prevData)
}
}

componentWillReceiveProps(np) {
const { firebase, firestore } = this.store
const { firestore } = this.store
const inputAsFunc = createCallable(dataOrFn)
const data = inputAsFunc(np, this.store)
// Handle a data parameter having changed
if (firebase.firestore && !isEqual(data, this.prevData)) {
// UnWatch all current events
firestore.unsetListeners(this.prevData)

// Handle changes to data
if (this.firestoreIsEnabled && !isEqual(data, this.prevData)) {
const changes = this.getChanges(data, this.prevData)

this.prevData = data
// Watch new events
firestore.setListeners(data)

// Remove listeners for inactive subscriptions
firestore.unsetListeners(changes.removed)

// Add listeners for new subscriptions
firestore.setListeners(changes.added)
}
}

getChanges(data = [], prevData = []) {
const result = {}
result.added = filter(data, d => !some(prevData, p => isEqual(d, p)))
result.removed = filter(prevData, p => !some(data, d => isEqual(p, d)))
return result
}

render() {
const { firebase, firestore } = this.store
return (
Expand Down

0 comments on commit 6f0d646

Please sign in to comment.