the createUserProfileDocument()
method from firebase
is returning undefined for some reason, therefore, it's throwing an error on my broswer's console.
The error thrown is:
App.js:23 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'onSnapshot') at App.js:23:1
the code:
import React from 'react';
import './App.css';
import { connect } from 'react-redux';
import { Switch, Route } from 'react-router-dom';
import HomePage from './pages/homepage/homepage.component';
import ShopPage from './pages/shop/shop.component';
import Header from './components/header/header.componet';
import { auth, createUserProfileDocument } from './firebase/firebase.utils';
import SignInAndSignUpPage from './pages/sign-in-and-sign-up/sign-in-and-sign-up.component';
import { setCurrentUser } from './redux/user/user.actions';
class App extends React.Component {
unsubscribeFromAuth = null;
componentDidMount() {
const { setCurrentUser } = this.props;
this.unsubscribeFromAuth = auth.onAuthStateChanged(async (userAuth) => {
if (userAuth) {
const userRef = await createUserProfileDocument(userAuth);
console.log(userRef);
userRef.onSnapshot((snapshot) => {
setCurrentUser({
id: snapshot.id,
...snapshot.data(),
});
});
}
setCurrentUser(userAuth);
});
}
componentWillUnmount() {
this.unsubscribeFromAuth();
}
render() {
return (
<div className='App'>
<Header />
<Switch>
<Route exact path='/' component={HomePage} />
<Route exact path='/shop' component={ShopPage} />
<Route
exact
path='/signin'
component={SignInAndSignUpPage}
/>
</Switch>
</div>
);
}
}
const mapDispatchToProps = (dispatch) => ({
setCurrentUser: (user) => dispatch(setCurrentUser(user)),
});
export default connect(null, mapDispatchToProps)(App);
The portion of code related to my error is the following:
componentDidMount() {
const { setCurrentUser } = this.props;
this.unsubscribeFromAuth = auth.onAuthStateChanged(async (userAuth) => {
if (userAuth) {
const userRef = await createUserProfileDocument(userAuth);
console.log(userRef);
userRef.onSnapshot((snapshot) => { // This is Line 23......
setCurrentUser({
id: snapshot.id,
...snapshot.data(),
});
});
}
setCurrentUser(userAuth);
});
}
I console.logged(userRef)
as you can see, and it returns undefined. This is my first experience with firebase
so I am not sure where the error is.
I googled and found an answer here in stackoverflow which is alike to my issue: TypeError: Cannot read properties of undefined (reading 'onSnapshot')
However, that problem is specifically related to how the developer was passing the method as an array and not a method, which does not help my situation.
EDIT: Adding firebase.utils
code.
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import 'firebase/compat/auth';
const config = {
apiKey: 'AIzaSyDxUMY8sUpOMAoxEyHo41ONilzjL2woWHk',
authDomain: 'crown-db-d4416.firebaseapp.com',
projectId: 'crown-db-d4416',
storageBucket: 'crown-db-d4416.appspot.com',
messagingSenderId: '887003208895',
appId: '1:887003208895:web:778f8f55a0ad2c72953a0a',
measurementId: 'G-6TGCRVN7D3',
};
export const createUserProfileDocument = async (userAuth, additionalData) => {
if (!userAuth) return;
const userRef = firestore.doc(`users/${userAuth.uid}`);
const snapShot = await userRef.get();
console.log(snapShot);
if (!snapShot.exists) {
const { displayName, email } = userAuth;
const createdAt = new Date();
try {
await userRef.set({
displayName,
email,
createdAt,
...additionalData,
});
} catch (error) {
console.log('Error creating user: ', error.message);
}
}
};
firebase.initializeApp(config);
export const auth = firebase.auth();
export const firestore = firebase.firestore();
const googleProvider = new firebase.auth.GoogleAuthProvider();
export const signInWithGoogle = () => {
auth
.signInWithPopup(googleProvider)
.then((res) => {
console.log(res.user);
})
.catch((error) => {
console.log(error.message);
});
};
export default firebase;
CodePudding user response:
Your createUserProfileDocument
function doesn't return anything, so that explains why this code then fails:
const userRef = await createUserProfileDocument(userAuth);
console.log(userRef);
userRef.onSnapshot((snapshot) => {
The solution is to return the userRef
from createUserProfileDocument
as your calling code expects:
export const createUserProfileDocument = async (userAuth, additionalData) => {
...
return userRef;
};