null is not an object while evaluating current user in firebase - javascript

im getting type error null is not an object evaluating firebase.auth().currentUser.uid
I am trying to get the current user id and store it into firebase database using an if statement logic for whether the user is an agent or client.
import * as firebase from "firebase";
// Your web app's Firebase configuration
var firebaseConfig = {
XXX
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
const UserId = firebase.auth().currentUser.uid;
export function login({ email, password }) {
firebase.auth().signInWithEmailAndPassword(email, password);
}
export function signup({ email, password, displayName }) {
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((userInfo) => {
console.log(userInfo);
userInfo.user
.updateProfile({ displayName: displayName.trim() })
.then((user) => {
if (this.state.checked == "first") {
firebase
.database()
.ref("client/" + UserId)
.child("client")
.update({ email, displayName, UserId });
} else {
firebase
.database()
.ref("agent/" + UserId)
.child("agent")
.update({ email, displayName, UserId });
}
});
});
}
export function subscribeToAuthChanges(authStateChanged) {
firebase.auth().onAuthStateChanged((user) => {
authStateChanged(user);
});
}

firebase.auth().currentUser will be null when no user is signed in. The error is telling you that is the case. You shouldn't try to access any properties on it until the sign-in completes successfully.
When sign-in does complete, you will have a user object delivered to your callback, so there is not even a need to use firebase.auth().currentUser at all here.
firebase
.auth()
.createUserWithEmailAndPassword(email, password)
.then((userInfo) => {
console.log(userInfo);
In your code above, userInfo.user is that current user object. Use it instead of firebase.auth().currentUser.

Related

How to upload document whenever a user signs up in firebase with custom users uid?

I am working with react and firebase ver 9. As firebase offers limited field and I need to send some more data while registering a user. I saw that you can do this while uploading document whenever a user signs up. I have written the code for it but when I run it only users are registered but my document doesn`t get uploaded.
Here`s my code:
import { useState } from "react"
import { auth, db } from "../Authentication/firebaseConfig"
import { createUserWithEmailAndPassword } from "firebase/auth"
import {
collection,
setDoc,
addDoc,doc
} from "firebase/firestore";
export const useSignup = () => {
const [error, setError] = useState(null)
const signup = async (email, password, displayName) => {
setError(null)
const current_user = await createUserWithEmailAndPassword(auth, email, password, displayName);
const uid = current_user.user.uid;
await addDoc(collection(db, "users"), {
uid: uid,
displayName,
email,
})
.then((res) => {
console.log('user signed up:', res.user)
})
.catch((err) => {
setError(err.message)
})
}
return { error, signup }
}
As stated by #Danial, the error was produced by Cloud Firestore Rules that is set to false.
Sample Rule:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Sample Firestore rule above will prohibit you to read and write to any collection and document. Changing it to true allows the public to read and write to Firestore.

Add username on createUserWithEmailAndPassword in Firebase with React

I want to add the username on the signup of the user and I am using the following code:
//Create Account With Email&Password
const createUser = (email, password, username) => {
return createUserWithEmailAndPassword(auth, email, password).then(() => {
updateProfile(auth.currentUser, {
displayName: username,
});
});
};
This is my useEffect in the same js file
useEffect(() => {
console.log('useEffect');
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
});
return () => unsubscribe();
}, []);
This code is adding the displayname successfully, but when I redirect to my account page the displayname is not directly showing up and I am getting a memory leak warning from the router-dom. Is there a cleaner and better way to do this?
I believe it's because the account page loads before firebase loads the auth data, you can use something like
onAuthStateChanged(auth,(user)=>{
if(user){
getUserName = auth.currentUser.displayName;
// Load the rest of the page
}
}
at your redirected user page,assuming you are using the right auth state, which you can refer from here https://firebase.google.com/docs/auth/web/auth-state-persistence?authuser=0

google auth and firebase persistence

heres my log in function, it works it logs you in via google account, but on refresh it does not stay logged in. what am I doing wrong? sorry I have no idea how to format the code to show correctly here.
const provider = new GoogleAuthProvider();
const login = () =>
{setPersistence(auth, browserSessionPersistence)
.then(()=> {
signInWithPopup(auth, provider)
.then((result) => {
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential?.accessToken;
// The signed-in user info.
const user = result.user;
//console.log({ credentials, token, user });
})
.then(() => {
setSignIn(true);
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
// The email of the user's account used.
const email = error.email;
// The AuthCredential type that was used.
const credential = GoogleAuthProvider.credentialFromError(error);
//console.log({ errorCode, errorMessage, email, credential });
});
})
};
Firebase automatically restores the user credentials when you restart the app, but your code only responds to the explicit sign in (signInWithPopup).
To pick up the automatic restore (and other changes in authentication state), you should use an auth state listener as shown in the first code sample in the documentation on getting the current user:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
var uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});
Since v9, the code has changed.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});

How can I update mobile number in firebase authentication using the updateProfie Method?

I am collecting name, email, phone and password when a user sign up. In the useFirebase hook, I am updating the displayName using updateProfile method of firebase.
This function is used for creating user.
const userCreate = (name, email, password, phone, history) => {
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
//User Create after registration
const newUser = { email, displayName: name, phoneNumber:phone };
const uid = auth.currentUser.uid
verifyEmail();
updateProfile(auth.currentUser, {
displayName: name,
phoneNumber:phone,
})
.then(() => {
console.log()
})
.catch((error) => {
});
history.replace('/');
})
.catch((error) => {
console.log(error)
})
}
After signup the displayName is updated. But I am not getting the phone number. How can I do that?
From the documentation on updating a user's profile:
You can update a user's basic profile information—the user's display name and profile photo URL—with the updateProfile method.
So there's no way to update the user's phone number with this function. The reason for this is that the phone number is part of a user's sign-in credentials, so needs to be updated through a dedicated method (similar to their password and email).
To update a user's phone number, call the updatePhoneNumber function as shown here:
// 'recaptcha-container' is the ID of an element in the DOM.
const applicationVerifier = new RecaptchaVerifier('recaptcha-container');
const provider = new PhoneAuthProvider(auth);
const verificationId = await provider.verifyPhoneNumber('+16505550101', applicationVerifier);
// Obtain the verificationCode from the user.
const phoneCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
await updatePhoneNumber(user, phoneCredential);

Create Firestore document only the first time a user signs in with google oAuth

I'm new to react and firebase and was trying to create a firestore document only during the creation of user.
Its working fine on the local provider as there sign in and sign up are two different things but when it comes to google o Auth both the options use same function.
So how do i create my initial documnet during creation of user via google o Auth as it just resets my entire document when i log out and log in back.
googleAuth function
function googleAuth(provider) {
return firebase
.auth()
.signInWithPopup(provider)
.then(async function createUserDb(userCredentials) {
await setDoc(doc(db, "users", userCredentials.user.uid), {myList: []},{ merge: true })
})
}
sign up and sign in functions
function signUp(email, password) {
return auth.createUserWithEmailAndPassword(email, password).then(
async function createUserDb(userCredentials) {
console.log(userCredentials.user.uid);
await setDoc(doc(db, "users", userCredentials.user.uid), {myList: []})
})
}
function signIn(email, password) {
return auth.signInWithEmailAndPassword(email, password)
}
my firestore users collection when a new user is created (google auth user here)
it should save the data even after sign in (local auth user here)
after scraping through some posts found .additionalUserInfo.isNewUser method which checks if the user has created new account or is already a user which fixed my issue.
Thank you for any help that you guys provided.
function googleAuth(provider) {
return firebase
.auth()
.signInWithPopup(provider)
.then(async function createUserDb(userCredentials) {
if(userCredentials.additionalUserInfo.isNewUser) {
await setDoc(doc(db, "users", userCredentials.user.uid), {myList: []},{ merge: true })
}
})
}

Categories

Resources