Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(auth): firestore profile's now contain timestamps for dates inst…
…ead of strings
  • Loading branch information
prescottprue committed Jan 21, 2018
commit 0f64cb6db91d9989fca9955d47ed74c5f75fb1bd
28 changes: 20 additions & 8 deletions src/actions/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from 'lodash'
import { actionTypes } from '../constants'
import { populate } from '../helpers'
import { stringToDate } from '../utils'
import {
getLoginMethodAndParams,
updateProfileOnRTDB,
Expand Down Expand Up @@ -209,14 +210,25 @@ export const createUserProfile = (dispatch, firebase, userData, profile) => {
.collection(config.userProfile)
.doc(userData.uid)
.get()
.then(
profileSnap =>
// update profile only if doesn't exist or if set by config
!config.updateProfileOnLogin && profileSnap.exists
? profileSnap.data()
: profileSnap.ref.update(omit(profile, ['providerData'])) // fixes issue with bad write
.then(() => profile) // Update the profile
)
.then(profileSnap => {
// Convert to JSON format (to prevent issue of writing invalid type to Firestore)
const userDataObject = userData.toJSON ? userData.toJSON() : userData
// Remove unnessesary auth params (configurable) and preserve types of timestamps
const newProfile = {
...omit(userDataObject, config.keysToRemoveFromAuth),
avatarUrl: userDataObject.photoURL, // match profile pattern used for RTDB
createdAt: stringToDate(userDataObject.createdAt),
lastLoginAt: stringToDate(userDataObject.lastLoginAt)
}
// Return if config for updating profile is not enabled and profile exists
if (!config.updateProfileOnLogin && profileSnap.exists) {
return profileSnap.data()
}
// Create/Update the profile
return profileSnap.ref
.set(newProfile, { merge: true })
.then(() => newProfile)
})
.catch((err) => {
// Error reading user profile
dispatch({ type: actionTypes.UNAUTHORIZED_ERROR, authError: err })
Expand Down
18 changes: 13 additions & 5 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @example
* import { constants } from 'react-redux-firebase'
* constants.actionsPrefix === '@@reactReduxFirebase' // true
*/
*/
export const actionsPrefix = '@@reactReduxFirebase'

/**
Expand Down Expand Up @@ -55,7 +55,7 @@ export const actionsPrefix = '@@reactReduxFirebase'
* @example
* import { actionTypes } from 'react-redux-firebase'
* actionTypes.SET === '@@reactReduxFirebase/SET' // true
*/
*/
export const actionTypes = {
START: `${actionsPrefix}/START`,
SET: `${actionsPrefix}/SET`,
Expand Down Expand Up @@ -166,7 +166,7 @@ export const actionTypes = {
* firestore helpers (**WARNING** Changing this will break firestoreConnect HOC.
* Do **NOT** change to `'firestore'`)
* @type {Object}
*/
*/
export const defaultConfig = {
userProfile: null,
presence: null,
Expand All @@ -183,7 +183,15 @@ export const defaultConfig = {
dispatchRemoveAction: false,
enableEmptyAuthChanges: true,
firebaseStateName: 'firebase',
attachAuthIsReady: false
attachAuthIsReady: false,
keysToRemoveFromAuth: [
'appName',
'apiKey',
'authDomain',
'redirectEventId',
'stsTokenManager',
'uid'
]
}

/**
Expand All @@ -192,7 +200,7 @@ export const defaultConfig = {
* @description List of all external auth providers that are supported
* (firebase's email/anonymous included by default).
* @private
*/
*/
export const supportedAuthProviders = [
'google',
'github',
Expand Down
11 changes: 9 additions & 2 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ export const getDisplayName = Component => {
return Component.displayName || Component.name || 'Component'
}

export default getDisplayName

export const wrapDisplayName = (BaseComponent, hocName) =>
`${hocName}(${getDisplayName(BaseComponent)})`

export const stringToDate = strInput => {
try {
return new Date(JSON.parse(strInput))
} catch (err) {
console.error('Error parsing string to date:', err.message || err) // eslint-disable-line no-console
return strInput
}
}