Firebase Reactjs get current user from context - reactjs

I'm new of Reactjs and I'd like to understand if the only way to get Firebase currentUser from context is through onAuthStateChanged.
I try to be more clear: let's say I signed-in by a "SignIn" component by using Firebase context and, after signed-in, I need to get currentUser in a different component, it seems to me the only way to get it is something like:
const [user, setUser] = useState(null);
...
useEffect(() => {
props.firebase.auth.onAuthStateChanged(authUser => {
if (!!authUser) {
setUser(authUser);
}
});
}, []);
Is it true?
Thanks

You can call on a current user any time
You can use this auth function
const user = firebase.auth().currentUser;
You don't have to store it. Unless you want to.

Thanks to who reply my question, I found the answer in this detailed article.

Related

How to manage global states with React Query

i have a project that's using Nextjs and Supabase. I was using context API and now i'm trying to replace it for React Query, but i'm having a hard time doing it. First of all, can i replace context completely by React Query?
I created this hook to get the current user
export const getUser = async (): Promise<Profile> => {
const onFetch = await supabase.auth.getUser();
const userId = onFetch.data.user?.id;
let { data, error } = await supabase
.from("profiles")
.select()
.eq("id", userId)
.single();
return data;
};
export const useUser = () => {
return useQuery(["user"], () => getUser());
};
I'm not sure how to trigger it. When i was using context i was getting the user as this. If data, then it would redirect to the HomePage
let { data, error, status } = await supabase
.from("profiles")
.select()
.eq("id", id)
.single();
if (data) {
setUser(data);
return true;
}
Since i was getting the user before redirecting to any page, when i navigated to profile page, the user was already defined. How can i get the user before anything and keep this state? I suppose that once the user is already defined, at the profile component i can call useUser and just use it's data. But it's giving me undefined when i navigate to profile, i suppose that it's fetching again.
const { data, isLoading } = useUser();
But it's giving me undefined when i navigate to profile, i suppose that it's fetching again.
Once data is fetched when you call useUser, it will not be removed anymore (unless it can be garbage collected after it has been unused for some time). So if you do a client side navigation (that is not a full page reload) to another route, and you call useUser there again, you should get data back immediately, potentially with a background refetch, depending on your staleTime setting).
If you're still getting undefined, one likely error is that you are creating your QueryClient inside your app and it thus gets re-created, throwing the previous cache away. You're not showing how you do that so it's hard to say. Maybe have a look at these FAQs: https://tkdodo.eu/blog/react-query-fa-qs#2-the-queryclient-is-not-stable

React order of execution

I have a code that sets a state of current user logged in, and i want to do something if the user is logged in, but the User information doesnt gets updated in order. I cannot explain it right, so ill right the code below.
const handleSubmit = async (event) => {
event.preventDefault()
try {
const user = await signInAuthUserWithEmailAndPassword(
email,
password
);
const test = await setCurrentUser(user)
console.log(currentUser)
currentUser ? setToggleSuccess(true) : setToggleSuccess(false)
resetFormFields();
console.log(currentUser)
} catch (error) {
the console.log's return 'null', but they are below the setCurrentUser. How to make the setCurrentUser get triggered before the console.logs?
setCurrentUser is definitely an async function but even if you add await while calling it, the state won't be updated instantaneously. You will get the changes in useEffect only. I will suggest you to use the variable user in the function defined instead of using "currentUser".
Also, if your resetFormFields uses currentUser then it should be called inside useEffect.
Note:- I am assuming that the current user is a react state and setCurrentUser is used to update the state.

Updating two states at the same time puts the component in infinite loop - REACTJS WITH DJANGO BACKEND

I am a beginner at ReactJs and I'm creating an app using ReactJs and Django as backend.
I have created a sign in functionality and the signed-in user's pfp gets displayed in the navbar.
So in my sub-component ShowNavUser() I have 2 states: username and userImage. I make an ajax(Axios) call to the Django backend and once that is done I am updating the username and userImage states with the data returned.
Here is the code:
const [username, setUsername] = useState();
const [userImage, setUserImage] = useState();
const url = `http://localhost:8000/users/${props.loggedUser}`;
useEffect(() => {
axios.get(url).then((response) => {
setUsername(response.data.username);
setUserImage(response.data.profile_pic);
});
});
Now as a result of that, I am getting a loop of requests to the backend which is freezing my app.
Can someone please help me with this?
Thanks
Actually, your code is going into an infinite loop due to a minor error. Just fix it.
useEffect(() => {
axios.get(url).then((response) => {
setUsername(response.data.username);
setUserImage(response.data.profile_pic);
});
}, []); // added this []

how can ı handle react with firebase authentication problem?

I am trying develop user authentication page in react with firebase.
I can sign in but then sign in doesn't change to sign out.
what is the problem?
const handleAuthentication = () => {
if(user){
auth.signOut();
}
}
<div onClick={handleAuthentication}
className="header_option">
<span
className="header_optionLineOne" >Hello, Guest</span>
<span
className="header_optionLineTwo" >{user ?
'Sign Out': 'Sign In'}</span>
</div>
Probably the user is actually signed out, but the UI is not rerendering as it doesn't know about the change.
To fix this, you'll want to store the user in the component's state, with either setState or a useState hook:
const [user, setUser] = useState(null);
auth.onAuthStateChanged((user) => {
setUser(user);
});
With the user being part of the state, the call to setUser(user) will cause the component to rerender and thus show the updated (lack of) user information.
Also see the first code snippet in the Firebase documentation on getting the current user.

React state is empty inside useEffect

Currently I'm building a pusher chat app with react. I'm trying to keep a list of online users. I'm using this code below:
const [users, setUsers] = useState([]);
useEffect(() => { // UseEffect so only called at first time render
window.Echo.join("server.0")
.here((allUsers) => {
let addUsers = [];
allUsers.map((u) => {
addUsers.push(u.name)
})
setUsers(addUsers);
})
.joining((user) => {
console.log(`User ${user.name} joined`);
setUsers([users, user]);
})
.leaving((user) => {
console.log(`User ${user.name} left`);
let addUsers = users;
addUsers.filter((u) => {
return u !== user.name;
})
setUsers(addUsers);
})}, []);
Whenever I subscribe to the pusher channel, I receive the users that are currently subscribed and the state is set correctly. All subscribed users are showing. However when a new user joins/leaves, the .joining/.leaving method is called and the users state is empty when I console log it. This way the users state is being set to only the newly added user and all other users are being ignored. I'm new to react so there is probably a simple explanation for this. I was not able to find the answer myself tough. I would really appreciate your help.
I saw the problem in joining. You need to update setState like this: setUsers([...users, user.name]);
And leaving also need to update:
const addUsers = users.filter((u) => {
return u !== user.name;
});
setUsers(addUsers);
here should also rewrite:
let addUsers = allUsers.map((u) => u.name);
setUsers(addUsers);
I found the issue. The problem is that when accessing state from within a callback funtion, it always returns the initial value. In my case an empty array. It does work when using a reference variable. I added the following lines:
const [users, _setUsers] = useState([]);
const usersRef = React.useRef(users);
const setUsers = data => {
usersRef.current = data;
_setUsers(data);
}
Each time I update the users state, I use the setUsers function. Now when I acces the state from inside my callback function with usersRef.current I get the latest state.
Also I used the code from the answer of #Viet to update the values correctly.

Resources