Skip to content

Commit aebe5cd

Browse files
authored
v3.0.3
* feat(profile): add promise support for `profileFactory` - @dannyvaughton * fix(types): fix `firestore.delete` return type - @rscotten * feat(tests): add test for promise support of profile factory * feat(tests): add tests for all top level methods of `createFirebaseInstance`
2 parents 255b810 + bd3a155 commit aebe5cd

File tree

8 files changed

+885
-42
lines changed

8 files changed

+885
-42
lines changed

docs/contributing.md

+22
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,25 @@ It is often convenient to run a local version of `react-redux-firebase` within a
8484
**What Happened?**
8585

8686
This error most often appears due to Webpack config. A common pattern is to provide `exclude: [/node_modules/]` setting to [babel-loader](https://github.com/babel/babel-loader), which keeps the loader from transforming code within the `node_modules` folder. Now that we have used `npm link`, your project points to your local version of `react-redux-firebase` instead of the one in your `node_modules` folder, so we have to tell the loader to also exclude transforming `react-redux-firebase`.
87+
88+
* `Invalid hook call. Hooks can only be called inside of the body of a function component`:
89+
90+
**Common Solution**
91+
92+
Add `react` as an alias in Webpack:
93+
94+
**Webpack**
95+
96+
```js
97+
{
98+
resolve: {
99+
alias: {
100+
react: path.resolve('./node_modules/react')
101+
}
102+
}
103+
}
104+
```
105+
106+
**What Happened?**
107+
108+
This error often occurs when you have multiple instances of React loading after using `npm link`. The easiest fix is by setting React as an alias in Webpack.

index.d.ts

+17-8
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,9 @@ export type ReduxFirestoreQueries =
433433
* Function that recieves component props and returns
434434
* a list of query configuration objects for redux-firestore
435435
*/
436-
export type ReduxFirestoreQueriesFunction = (props?: any) => ReduxFirestoreQueries
436+
export type ReduxFirestoreQueriesFunction = (
437+
props?: any
438+
) => ReduxFirestoreQueries
437439

438440
/**
439441
* Firestore instance extended with methods which dispatch redux actions.
@@ -477,7 +479,7 @@ interface ExtendedFirestoreInstance extends FirestoreTypes.FirebaseFirestore {
477479
* Delete a document within firestore.
478480
* @see https://github.com/prescottprue/redux-firestore#delete
479481
*/
480-
delete: (docPath: string | ReduxFirestoreQuerySetting) => void
482+
delete: (docPath: string | ReduxFirestoreQuerySetting) => Promise<void>
481483

482484
/**
483485
* Executes the given updateFunction and then attempts to commit the changes applied within the
@@ -541,7 +543,9 @@ export interface WithFirestoreProps {
541543
firestore: FirestoreTypes.FirebaseFirestore &
542544
ExtendedFirestoreInstance &
543545
FirestoreStatics
544-
firebase: ExtendedFirebaseInstance & ExtendedAuthInstance & ExtendedStorageInstance
546+
firebase: ExtendedFirebaseInstance &
547+
ExtendedAuthInstance &
548+
ExtendedStorageInstance
545549
dispatch: Dispatch
546550
}
547551

@@ -642,7 +646,7 @@ interface ExtendedAuthInstance {
642646
* @see https://react-redux-firebase.com/docs/api/firebaseInstance.html#signinwithphonenumber
643647
*/
644648
signInWithPhoneNumber: AuthTypes.FirebaseAuth['signInWithPhoneNumber']
645-
649+
646650
/**
647651
* Update user's email
648652
* @param newEmail - Update to be auth object
@@ -775,7 +779,9 @@ interface ExtendedStorageInstance {
775779
}
776780

777781
export interface WithFirebaseProps<ProfileType> {
778-
firebase: ExtendedAuthInstance & ExtendedStorageInstance & ExtendedFirebaseInstance
782+
firebase: ExtendedAuthInstance &
783+
ExtendedStorageInstance &
784+
ExtendedFirebaseInstance
779785
}
780786

781787
/**
@@ -843,7 +849,9 @@ export function fixPath(path: string): string
843849
* integrations into external libraries such as redux-thunk and redux-observable.
844850
* @see https://react-redux-firebase.com/docs/api/getFirebase.html
845851
*/
846-
export function getFirebase(): ExtendedFirebaseInstance & ExtendedAuthInstance & ExtendedStorageInstance
852+
export function getFirebase(): ExtendedFirebaseInstance &
853+
ExtendedAuthInstance &
854+
ExtendedStorageInstance
847855

848856
/**
849857
* Get a value from firebase using slash notation. This enables an easy
@@ -882,7 +890,9 @@ export function isLoaded(...args: any[]): boolean
882890
* instance is gathered from `ReactReduxFirebaseContext`.
883891
* @see https://react-redux-firebase.com/docs/api/useFirebase.html
884892
*/
885-
export function useFirebase(): ExtendedFirebaseInstance & ExtendedAuthInstance & ExtendedStorageInstance
893+
export function useFirebase(): ExtendedFirebaseInstance &
894+
ExtendedAuthInstance &
895+
ExtendedStorageInstance
886896

887897
/**
888898
* React hook that automatically listens/unListens
@@ -925,7 +935,6 @@ export function useFirestoreConnect<TInner>(
925935
| string
926936
): void
927937

928-
929938
/**
930939
* Populate with data from multiple paths within redux.
931940
* @param state - Firebase state object (state.firebase in redux store)

package-lock.json

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

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-redux-firebase",
3-
"version": "3.0.2",
3+
"version": "3.0.3",
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",
@@ -127,7 +127,7 @@
127127
"uglifyjs-webpack-plugin": "^2.1.3",
128128
"webpack": "^4.41.0",
129129
"webpack-bundle-analyzer": "^2.9.0",
130-
"webpack-cli": "^3.1.2",
130+
"webpack-cli": "^3.3.9",
131131
"ws": "^3.2.0",
132132
"xmlhttprequest": "^1.8.0"
133133
},

src/actions/auth.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -273,24 +273,29 @@ export const watchUserProfile = (dispatch, firebase) => {
273273
* @returns {Promise} Resolves after creating user profile
274274
* @private
275275
*/
276-
export const createUserProfile = (dispatch, firebase, userData, profile) => {
276+
export const createUserProfile = async (
277+
dispatch,
278+
firebase,
279+
userData,
280+
profile
281+
) => {
277282
const { _: { config } } = firebase
278283
if (!config.userProfile || (!firebase.database && !firebase.firestore)) {
279-
return Promise.resolve(userData)
284+
return userData
280285
}
281286
// use profileFactory if it exists in config
282287
if (typeof config.profileFactory === 'function') {
283288
// catch errors in user provided profileFactory function
284289
try {
285-
profile = config.profileFactory(userData, profile, firebase) // eslint-disable-line no-param-reassign
290+
profile = await config.profileFactory(userData, profile, firebase) // eslint-disable-line no-param-reassign
286291
} catch (err) {
287292
/* eslint-disable no-console */
288293
console.error(
289294
'Error occured within profileFactory function:',
290295
err.message || err
291296
)
292297
/* eslint-enable no-console */
293-
return Promise.reject(err)
298+
throw err
294299
}
295300
}
296301

test/unit/actions/auth.spec.js

+25-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import {
2828
createSuccessStub,
2929
onAuthStateChangedSpy,
3030
firebaseWithConfig,
31-
createFailureStub
31+
createFailureStub,
32+
sleep
3233
} from '../../utils'
3334
// import { promisesForPopulate } from 'utils/populate'
3435

@@ -262,7 +263,7 @@ describe('Actions: Auth -', () => {
262263
expect(profile).to.equal(userData)
263264
})
264265

265-
it('creates profile using profileFactory if it exists', async () => {
266+
it('creates profile using profileFactory sync function if it exists', async () => {
266267
const userData = {
267268
uid: '123',
268269
email: 'test@test.com',
@@ -279,6 +280,28 @@ describe('Actions: Auth -', () => {
279280
expect(profileFactory).to.have.been.calledOnce
280281
})
281282

283+
it('creates profile using profileFactory promise function if it exists', async () => {
284+
const userData = {
285+
uid: '123',
286+
email: 'test@test.com',
287+
providerData: [{}]
288+
}
289+
const profileObj = { some: 'asdf' }
290+
/* eslint-disable jsdoc/require-jsdoc */
291+
async function profileFactoryPromise() {
292+
await sleep(500)
293+
return profileObj
294+
}
295+
const profileFactory = sinon.spy(profileFactoryPromise)
296+
const profile = await createUserProfile(
297+
dispatch,
298+
firebaseWithConfig({ profileFactory }),
299+
userData
300+
)
301+
expect(profile).to.have.property('some', profileObj.some)
302+
expect(profileFactory).to.have.been.calledOnce
303+
})
304+
282305
it('rejects for error in profileFactory function', async () => {
283306
const profileFactory = () => {
284307
throw new Error('test')

0 commit comments

Comments
 (0)