skip to Main Content

I am trying to show a page only if the current user is logged in, else ask them to login. I am using firebase authentication to achieve this.

import Head from "next/head";
import { auth } from "../../components/firebase";
import { onAuthStateChanged } from "firebase/auth";
import Login from "../Login";
import AddProperty from "../../components/AddProperty";
const Properties = () => {
  const user = auth.currentUser;
  return (
    <>
      <Head>
        <title>Add Property</title>
        <meta name="keywords" content="web dev" />
      </Head>
      <h1>Add Property</h1>
      <p>Welcome to the add Property new</p>

      {onAuthStateChanged(auth, (user) => {
        if (user) {
          {
            <AddProperty />;
          }
        } else {
          <Login />;
        }
      })}
    </>
  );
};

export default Properties;

enter image description here

2

Answers


  1. onAuthStateChanged returns a function that unsubscribes the registered event handler for listening the firebase auth state. You need to store the authenticated user in a separate state and consume it in a JSX statement.

    import Head from "next/head";
    import { useEffect, useState } from 'react';
    import { auth } from "../../components/firebase";
    import { onAuthStateChanged } from "firebase/auth";
    import Login from "../Login";
    import AddProperty from "../../components/AddProperty";
    
    const Properties = () => {
    
      const [user, setUser] = useState();
      
      useEffect(() => {
        const unsubscribe = onAuthStateChanged(
          auth.currentUser, 
          authUser => {
            setUser(authUser);
          }
        );
        
        return () => {
          unsubscribe();
        };
      }, [setUser]);
    
      return (
        <>
          <Head>
            <title>Add Property</title>
            <meta name="keywords" content="web dev" />
          </Head>
          <h1>Add Property</h1>
          <p>Welcome to the add Property new</p>
          {user ? (<AddProperty />) : (<Login />)}
        </>
      );
    };
    
    export default Properties;
    
    Login or Signup to reply.
  2. Not very familiar with Firebase but with a quick look at the docks, and being already familiar with React, here is my take.

    Any data that effects the way React renders should be loaded in state, in your case, a useState() hook.

    In Addition, I’ve basically ripped an example of what you’re trying to do straight from the Firebase docs, and used it here. The static function is left outside the component, as it doesn’t benefit from a re-render.

    import Head from 'next/head';
    import { useEffect, useState } from 'react';
    import { getAuth, onAuthStateChanged } from 'firebase/auth';
    import Login from '../Login';
    import AddProperty from '../../components/AddProperty';
    
    const auth = getAuth();
    
    const Properties = () => {
      const [user, setUser] = useState(null);
    
      useEffect(() => {
        onAuthStateChanged(auth, user => {
          if (user) {
            setUser(user);
          } else {
            setUser(false);
          }
        });
      }, [setUser]);
    
      return (
        <>
          <Head>
            <title>Add Property</title>
            <meta name='keywords' content='web dev' />
          </Head>
          <h1>Add Property</h1>
          <p>Welcome to the add Property new</p>
          {user ? <AddProperty /> : <Login />}
        </>
      );
    };
    
    export default Properties;
    

    Also I’m not sure of how often you want this user data pulled from a render, so this implementation runs onAuthStateChanged() on every render.

    Hope this helps. Any issues, just comment and I’ll try and help.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search