search

Home  >  Q&A  >  body text

Conditionally rendering Next.js based components: How to depend on whether the request comes from an authenticated Firebase user?

<p><strong>Note: </strong>I am using Next.js 13 and the <code>app/</code> directory. </p> <hr /> <p>I'm learning Firebase and Next.js and I'm trying to understand how to solve a toy problem. Let's say I have a <code>Home()</code>Component</p> like this <p><strong><code>/app/page.jsx</code></strong></p> <pre class="brush:php;toolbar:false;">export default function Home() { return ( <main> <h1>Hello World</h1> <p>Only authenticated users can see this text</p> </main> ) }</pre> <p>My goal is to conditionally render everything in <code><p>...</p></code> based on whether the user requesting the page is a logged in user. Firebase renders this component server side using JWT, Next.js 13, so I believe this is possible, but I can't figure out how to do it. </p> <p>I know about onAuthStateChanged, but as far as I know this can only be used on the client side. (Savvy users can still view this protected content.) How do I protect this content <em>server-side</em>? </p>
P粉616111038P粉616111038537 days ago596

reply all(1)I'll reply

  • P粉037880905

    P粉0378809052023-08-27 12:25:17

    To check if the user is logged in, you can use the 'onAuthStateChanged' method.

    Store this information in the component's state, or use it to conditionally render parts of the component.

    import React, { useEffect, useState } from 'react';
    import firebase from 'firebase/app';
    import 'firebase/auth';
    
    export default function Home() {
      const [user, setUser] = useState(null);
    
      useEffect(() => {
        const unsubscribe = firebase.auth().onAuthStateChanged(user => {
      setUser(user);
      });
        return () => unsubscribe();
      }, []);
    
      return (
        <main>
          <h1>Hello World</h1>
          {user ? (
            <p>authenticated user</p>
          ) : null}
        </main>
      );
    }

    To perform user authentication on the server side, Next.js provides 'getServerSideProps' to get the user's authentication status

    import firebase from 'firebase/app';
    import 'firebase/auth';
    
    export default function Home({ user }) {
      return (
        <main>
          <h1>Hello World</h1>
          {user ? (
            <p>authenticated user</p>
          ) : null}
        </main>
      );
    }
    
    export async function getServerSideProps(context) {
      const user = await new Promise((resolve, reject) => {
        firebase.auth().onAuthStateChanged(user => {
          resolve(user);
        });
      });
    
      return {
        props: {
          user,
        },
      };
    }

    Updated solution:

    Create a server-side route

    import firebase from 'firebase/app';
    import 'firebase/auth';
    import express from 'express';
    
    const app = express();
    
    app.get('/api/user', async (req, res) => {
      const user = await new Promise((resolve, reject) => {
        firebase.auth().onAuthStateChanged(user => {
          resolve(user);
        });
      });
    
      res.send(user);
    });
    
    app.listen(3000, () => {
      console.log('Server started at http://localhost:3000');
    });

    Client code

    import React, { useState, useEffect } from 'react';
    import axios from 'axios';
    
    export default function Home() {
      const [user, setUser] = useState(null);
    
      useEffect(() => {
        const fetchUser = async () => {
          const res = await axios.get('http://localhost:3000/api/user');
          const user = res.data;
    
          setUser(user);
        };
    
        fetchUser();
      }, []);
    
      return (
        <main>
          <h1>Hello World</h1>
          {user ? (
            <p>authenticated user</p>
          ) : null}
        </main>
      );
    }

    reply
    0
  • Cancelreply