Skip to content

Commit 51ce8db

Browse files
authored
v2.1.5
* fix(storage): `uploadFile` no longer errors out due to downloadURLs not being defined (v5 Firebase SDK) - prescottprue#480 * fix(examples): add `recompose` to firestore example's dependencies * feat(auth): use new `signInAndRetrieveDataWithCustomToken` firebase login method - prescottprue#467 - @kadikraman
2 parents c5b6680 + 0b40ada commit 51ce8db

File tree

9 files changed

+144
-45
lines changed

9 files changed

+144
-45
lines changed

examples/complete/firestore/package-lock.json

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

examples/complete/firestore/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"react-google-button": "*",
1414
"react-redux": "^4.4.5",
1515
"react-redux-firebase": "latest",
16+
"recompose": "^0.27.1",
1617
"redux": "^3.6.0",
1718
"redux-firestore": "latest"
1819
},

examples/complete/firestore/src/config.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
export const firebase = {
2-
apiKey: "AIzaSyBTvAcJwsN8iygsnwAZyzIuy1uleYEpWIo",
3-
authDomain: "redux-firestore.firebaseapp.com",
4-
databaseURL: "https://redux-firestore.firebaseio.com",
5-
projectId: "redux-firestore",
6-
storageBucket: "redux-firestore.appspot.com",
7-
messagingSenderId: "502471151289"
2+
apiKey: "AIzaSyCTUERDM-Pchn_UDTsfhVPiwM4TtNIxots",
3+
authDomain: "redux-firebasev3.firebaseapp.com",
4+
databaseURL: "https://redux-firebasev3.firebaseio.com",
5+
projectId: "redux-firebasev3",
6+
storageBucket: "redux-firebasev3.appspot.com",
7+
messagingSenderId: "823357791673"
88
}
99

1010
export const rrfConfig = {

package-lock.json

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

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-redux-firebase",
3-
"version": "2.1.4",
3+
"version": "2.1.5",
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",

src/actions/auth.js

+25-13
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,9 @@ export const createUserProfile = (dispatch, firebase, userData, profile) => {
247247
if (!config.updateProfileOnLogin && profileSnap.exists) {
248248
return profileSnap.data()
249249
}
250-
251-
let newProfile = {}
250+
let newProfile = profile
252251
// If the user did supply a profileFactory, we should use the result of it for the new Profile
253-
if (isFunction(config.profileFactory)) {
254-
newProfile = profile
255-
} else {
252+
if (!newProfile) {
256253
// Convert to JSON format (to prevent issue of writing invalid type to Firestore)
257254
const userDataObject = userData.uid
258255
? userData.toJSON ? userData.toJSON() : userData
@@ -451,13 +448,23 @@ export const login = (dispatch, firebase, credentials) => {
451448
if (!userData) return Promise.resolve(null)
452449

453450
// For email auth return uid (createUser is used for creating a profile)
454-
if (method === 'signInWithEmailAndPassword') {
451+
if (
452+
[
453+
'signInWithEmailAndPassword',
454+
'signInAndRetrieveDataWithEmailAndPassword'
455+
].includes(method)
456+
) {
455457
return { user: userData }
456458
}
457459
// TODO: Only call createUserProfile once, and just pass different settings
458460

459461
// For token auth, the user key doesn't exist. Instead, return the JWT.
460-
if (method === 'signInWithCustomToken') {
462+
if (
463+
[
464+
'signInWithCustomToken',
465+
'signInAndRetrieveDataWithCustomToken'
466+
].includes(method)
467+
) {
461468
if (!firebase._.config.updateProfileOnLogin) {
462469
return { user: userData }
463470
}
@@ -487,12 +494,17 @@ export const login = (dispatch, firebase, credentials) => {
487494
// Create profile when logging in with external provider
488495
const user = userData.user || userData
489496

490-
return createUserProfile(dispatch, firebase, user, {
491-
email: user.email,
492-
displayName: user.providerData[0].displayName || user.email,
493-
avatarUrl: user.providerData[0].photoURL,
494-
providerData: user.providerData
495-
}).then(profile => ({ profile, ...userData }))
497+
return createUserProfile(
498+
dispatch,
499+
firebase,
500+
user,
501+
credentials.profile || {
502+
email: user.email,
503+
displayName: user.providerData[0].displayName || user.email,
504+
avatarUrl: user.providerData[0].photoURL,
505+
providerData: user.providerData
506+
}
507+
).then(profile => ({ profile, ...userData }))
496508
})
497509
.catch(err => {
498510
dispatchLoginError(dispatch, err)

src/utils/auth.js

+17
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ export const getLoginMethodAndParams = (firebase, creds) => {
9797
return { method: 'signInWithRedirect', params: [authProvider] }
9898
}
9999
if (token) {
100+
const tokenAuth = firebase.auth().signInAndRetrieveDataWithCustomToken
101+
102+
if (tokenAuth) {
103+
return { method: 'signInAndRetrieveDataWithCustomToken', params: [token] }
104+
}
105+
100106
return { method: 'signInWithCustomToken', params: [token] }
101107
}
102108
if (phoneNumber) {
@@ -110,6 +116,17 @@ export const getLoginMethodAndParams = (firebase, creds) => {
110116
params: [phoneNumber, applicationVerifier]
111117
}
112118
}
119+
120+
const emailPasswordAuth = firebase.auth()
121+
.signInAndRetrieveDataWithEmailAndPassword
122+
123+
if (emailPasswordAuth) {
124+
return {
125+
method: 'signInAndRetrieveDataWithEmailAndPassword',
126+
params: [email, password]
127+
}
128+
}
129+
113130
return { method: 'signInWithEmailAndPassword', params: [email, password] }
114131
}
115132

src/utils/storage.js

+32-19
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ export function deleteFile(firebase, { path, dbPath }) {
4646
* @param {Object} uploadTaskSnapshot - Snapshot from storage upload task
4747
* @return {Function} Function for handling upload result
4848
*/
49-
function createUploadMetaResponseHandler({ fileData, uploadTaskSnapshot }) {
49+
function createUploadMetaResponseHandler({
50+
fileData,
51+
firebase,
52+
uploadTaskSnapshot
53+
}) {
5054
/**
5155
* Converts upload meta data snapshot into an object (handling both
5256
* RTDB and Firestore)
@@ -55,18 +59,37 @@ function createUploadMetaResponseHandler({ fileData, uploadTaskSnapshot }) {
5559
* @return {Object} Upload result including snapshot, key, File
5660
*/
5761
return function uploadResultFromSnap(metaDataSnapshot) {
62+
const { useFirestoreForStorageMeta } = firebase._.config
5863
const result = {
5964
snapshot: metaDataSnapshot,
6065
key: metaDataSnapshot.key || metaDataSnapshot.id,
6166
File: fileData,
6267
metaDataSnapshot,
6368
uploadTaskSnapshot,
6469
// Support legacy method
65-
uploadTaskSnaphot: uploadTaskSnapshot
70+
uploadTaskSnaphot: uploadTaskSnapshot,
71+
createdAt: useFirestoreForStorageMeta
72+
? firebase.firestore.FieldValue.serverTimestamp()
73+
: firebase.database.ServerValue.TIMESTAMP
6674
}
6775
if (metaDataSnapshot.id) {
6876
result.id = metaDataSnapshot.id
6977
}
78+
// Handle different downloadURL patterns (Firebase JS SDK v5.*.* vs v4.*.*)
79+
if (metaDataSnapshot.downloadURLs && metaDataSnapshot.downloadURLs[0]) {
80+
// Only attach downloadURL if downloadURLs is defined (not defined in v5.*.*)
81+
result.downloadURL = metaDataSnapshot.downloadURLs[0]
82+
} else if (
83+
uploadTaskSnapshot.ref &&
84+
typeof uploadTaskSnapshot.ref.getDownloadURL === 'function'
85+
) {
86+
// Get downloadURL and attach to response
87+
return uploadTaskSnapshot.ref.getDownloadURL().then(downloadURL => ({
88+
...result,
89+
downloadURL
90+
}))
91+
}
92+
7093
return result
7194
}
7295
}
@@ -87,34 +110,24 @@ export function writeMetadataToDb({
87110
dbPath,
88111
options
89112
}) {
90-
const {
91-
metadata: { name, fullPath, downloadURLs, size, contentType }
92-
} = uploadTaskSnapshot
93113
// Support metadata factories from both global config and options
94114
const { fileMetadataFactory, useFirestoreForStorageMeta } = firebase._.config
95115
const { metadataFactory } = options
96116
const metaFactoryFunction = metadataFactory || fileMetadataFactory
97117

98-
// File metadata object
99-
const originalFileMeta = {
100-
name,
101-
fullPath,
102-
size,
103-
contentType,
104-
downloadURL: downloadURLs[0],
105-
createdAt: useFirestoreForStorageMeta
106-
? firebase.firestore.FieldValue.serverTimestamp()
107-
: firebase.database.ServerValue.TIMESTAMP
108-
}
109-
110118
// Apply fileMetadataFactory if it exists in config
111119
const fileData = isFunction(metaFactoryFunction)
112-
? metaFactoryFunction(uploadTaskSnapshot, firebase, originalFileMeta)
113-
: originalFileMeta
120+
? metaFactoryFunction(
121+
uploadTaskSnapshot,
122+
firebase,
123+
uploadTaskSnapshot.metadata
124+
)
125+
: uploadTaskSnapshot.metadata
114126

115127
// Create the snapshot handler function
116128
const resultFromSnap = createUploadMetaResponseHandler({
117129
fileData,
130+
firebase,
118131
uploadTaskSnapshot
119132
})
120133

test/utils.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export const fakeFirebase = {
129129
email: 'test@test.com',
130130
providerData: [{}]
131131
}),
132-
signInWithCustomToken: () => {
132+
signInAndRetrieveDataWithCustomToken: () => {
133133
return Promise.resolve({
134134
toJSON: () => ({
135135
stsTokenManager: {

0 commit comments

Comments
 (0)