'Cannot read property of undefined data() Firebase
I'm trying to implement redux saga in my old project and i get strange error. I'm getting back the userData with all user details but my middleware logger tells me that sign_in_failed fires instead of sign_in_success with this error:
Cannot read property of undefined data() Firebase.
So i tried to do optional chaining and i also tried the old way of deep property check (with &&) but this didnt help. Also, i cant anymore perform a stripe payments due to this error because stripe cant see the user.
UserSaga.jsx
import { takeLatest, all, call, put } from 'redux-saga/effects'
import { USER_ACTIONS_TYPES } from '../../actions/user/userActionsTypes'
import {
signInSuccess,
signInFailed,
signUpSuccess,
signUpFailed,
signOutSuccess,
signOutFailed
} from '../../actions/user/userActionCreator'
import {
getCurrentUser,
createUserDocumentFromAuth,
createAuthUserWithEmailAndPassword,
signInWithGooglePopup,
signInAuthUserWithEmailAndPassword,
signOutAuthUser
} from '../../../database/firebase.config'
export function* getUserSnapshot(userAuth, additionalInformation) {
try {
const userSnapshot = yield call(
createUserDocumentFromAuth,
userAuth,
additionalInformation
);
//yield put(signInSuccess({ id: userSnapshot?.id, ...userSnapshot.data()}));
// console.log('userSnapshot2>>>>>>>>>', ...userSnapshot.data())
const id = userSnapshot?.id;
const userData = userSnapshot.data()
const {createdAt, email, password}= userData
yield put(signInSuccess({ id, createdAt, email, password }));
console.log('userSnapshot2>>>>>>>>>', userSnapshot)
} catch (error) {
yield put(signInFailed(error.message))
}
}
export function* signInWithGoogle() {
try {
const { user } = yield call(signInWithGooglePopup)
yield call(getUserSnapshot, user)
} catch (error) {
yield put(signInFailed(error))
}
}
export function* signInWIthEmail({ payload: { email, password } }) {
try {
const { user } = yield call(signInAuthUserWithEmailAndPassword, email, password)
yield call(getUserSnapshot, user)
} catch (error) {
yield put(signInFailed(error))
}
}
export function* isUserAuth() {
try {
const userAuth = yield call(getCurrentUser)
if (!userAuth) return;
yield call(getUserSnapshot, userAuth)
} catch (error) {
yield put(signInFailed(error))
}
}
export function* signUpWIthEmail({ payload: { email, password, displayName } }) {
try {
const { user } = yield call(createAuthUserWithEmailAndPassword, email, password)
yield put(signUpSuccess(user, { displayName }))
} catch (error) {
yield put(signUpFailed(error))
}
}
export function* signOut() {
try {
yield call(signOutAuthUser)
yield put(signOutSuccess())
} catch (error) {
yield put(signOutFailed(error))
}
}
export function* signInAfterSignUp({ payload: { user, additionalDetails } }) {
yield call(getUserSnapshot, user, additionalDetails)
}
export function* onGoogleSignInStart() {
yield takeLatest(USER_ACTIONS_TYPES.GOOGLE_SIGN_IN_START, signInWithGoogle)
}
export function* onCheckUserSession() {
yield takeLatest(USER_ACTIONS_TYPES.CHECK_USER_SESSION, isUserAuth)
}
export function* onEmailSignInStart() {
yield takeLatest(USER_ACTIONS_TYPES.EMAIL_SIGN_IN_START, signInWIthEmail)
}
export function* onSignUpStart() {
yield takeLatest(USER_ACTIONS_TYPES.SIGN_UP_START, signUpWIthEmail)
}
export function* onSignUpSuccess() {
yield takeLatest(USER_ACTIONS_TYPES.SIGN_IN_SUCCESS, signInAfterSignUp)
}
export function* onSignOutStart() {
yield takeLatest(USER_ACTIONS_TYPES.SIGN_OUT_START, signOut)
}
export function* userSagas() {
yield all([
call(onCheckUserSession),
call(onGoogleSignInStart),
call(onEmailSignInStart),
call(onSignUpStart),
call(onSignUpSuccess),
call(onSignOutStart),
call(onSignUpSuccess)
])
}
firebase.config.js
// Initialize Firebase and Oauth
initializeApp(firebaseConfig);
const googleProvider = new GoogleAuthProvider();
googleProvider.setCustomParameters({
prompt: "select_account"
})
//Initialize GAuth with popup signin method
export const auth = getAuth()
export const signInWithGooglePopup = () => signInWithPopup(auth, googleProvider)
// export const signInWithGoogleRedirect = () => signInWithRedirect(auth, googleProvider)
// Initialize Firestore
export const db = getFirestore()
// get the conllection created with all docs
export const getCollectionWithDocuments = async() => {
const collectionRef = collection(db, 'categories')
const q = query(collectionRef)
const querySnapShot = await getDocs(q)
return querySnapShot.docs.map(docSnapshot => docSnapshot.data())
}
//Create a user document
export const createUserDocumentFromAuth = async(userAuth, additionalInformation = {}) => {
if (!userAuth) return;
const userDocRef = doc(db, 'users', userAuth.uid)
// console.log('userRef>>', userDocRef)
const userSnapshot = await getDoc(userDocRef)
// console.log('just snapshot>>>', snapShot)
// console.log('if shot exist>>', snapShot.exists())
if (!userSnapshot.exists()) {
const { displayName, email } = userAuth
const createdAt = new Date();
try {
await setDoc(userDocRef, {
displayName,
email,
createdAt,
...additionalInformation
})
} catch (error) {
console.log("error creating user", error.message)
}
}
return userSnapshot;
}
export const createAuthUserWithEmailAndPassword = async(email, password) => {
if (!email || !password) return;
return await createUserWithEmailAndPassword(auth, email, password)
}
export const signInAuthUserWithEmailAndPassword = async(email, password) => {
if (!email || !password) return;
return await signInWithEmailAndPassword(auth, email, password)
}
export const signOutAuthUser = async() => await signOut(auth)
export const onAuthObserver = (callback) => onAuthStateChanged(auth, callback)
//Create a collection of document in firestore (call it ones inside useeffect to avoid mutations)
export const createCollectionWithDocuments = async(collectionName, objectsToAdd) => {
const collectionRef = collection(db, collectionName)
const batch = writeBatch(db)
objectsToAdd.forEach(object => {
const docRef = doc(collectionRef, object.title.toLowerCase())
batch.set(docRef, object)
})
await batch.commit()
console.log('collection created')
}
export const getCurrentUser = () => {
return new Promise((resolve, reject) => {
const unsubscribe = onAuthStateChanged(
auth,
(userAuth) => {
unsubscribe();
resolve(userAuth);
// console.log(userAuth)
},
reject)
})
}
userReducer.jsx
export const INITIAL_STATE = {
currentUser: null,
isLoading: false,
error: null
}
export const userReducer = (state = INITIAL_STATE, action) => {
const { type, payload } = action;
switch (type) {
case USER_ACTIONS_TYPES.SIGN_IN_SUCCESS:
return {
...state,
currentUser: payload,
error: null
}
case USER_ACTIONS_TYPES.SIGN_OUT_SUCCESS:
return {
...state,
currentUser: null
}
case USER_ACTIONS_TYPES.SIGN_OUT_FAILED:
case USER_ACTIONS_TYPES.SIGN_UP_FAILED:
case USER_ACTIONS_TYPES.SIGN_IN_FAILED:
return {
...state,
error: payload
}
default:
return state
}
}
userActions.js
export const emailSignInStart = (email, password) => createActions(USER_ACTIONS_TYPES.EMAIL_SIGN_IN_START, { email, password })
export const signInSuccess = user => createActions(USER_ACTIONS_TYPES.SIGN_IN_SUCCESS, user)
export const signInFailed = error => createActions(USER_ACTIONS_TYPES.SIGN_IN_FAILED, error)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
