Should I utilize Next.js API route or communicate directly with Firestore from the client side?

Greetings, I am new to Next.js and have a few queries regarding utilizing Firebase authentication on both the client side and server side. My project is set up with Firebase admin and client SDKs, and I have a signup page where users provide their name, email, and password.

Queries: [1]

After a user signs up using email and password with createUserWithEmailAndPassword on the client side, I want to save the authentication response (user's name and UID) to Firestore DB. Should I do this in the same submit handler as the authentication response?

const onSignup = async ({ email, password }: Tfields) => {
    try {
      const response = await auth.signup(email, password);
      / *** DO I save to firestore DB here ? **/
      // route to authenticated page
      router.push("/account");
    } catch (error) {   
        });
    }
};  

[2] If I need to call Firestore from the above handler, should I directly use the Firebase client-side SDK or create an API route called createDBUser in Next.js and call the API from the handler? Wouldn't connecting to Firestore via an API be safer than directly using the client-side SDK?

[3] For example, an authorized route like /account is essentially a statically generated page at build time. Won't this initially show nothing on the page, which isn't very SEO-friendly? Only the header SEO component will be visible until the Firebase client-side check occurs?

const Account = () => {
  const [user, setUser] = useState<any>(null);

  const handleUser = (user) => {
   setuser(user)
  }

   useEffect(() => {
     const unsubscribe = onIdTokenChanged(getAuth(), handleUser);
   return () => unsubscribe();
  }, []);

  return (
    <div>
      <Head>
        <title>Authorized User page</title>
        <meta
          name="description"
          content="this is John Doe's page with all his account pages"
        />
      </Head>
      {user && <div>
          <div>This is an authenticated account page</div>
      </div> }
    </div>
  );
};

export default Account;

Should I instead use getServerSideProps on the account page to check if a user is logged in before rendering it, rather than handling it in the useEffect? Wouldn't this ensure that all content is rendered on the server before being served to the user? Additionally, I would be able to include the user's name in the SEO header since it will be rendered on the server beforehand.

Answer №1

When it comes to interacting with Firestore, the decision to do so directly or through a server can vary depending on your specific circumstances. Is it really necessary to add another API route, verify user tokens, and then add data to Firestore when you can achieve the same outcome more efficiently and securely using security rules? In fact, you can easily add data to Firestore immediately after creating a user with createUserWithEmailAndPassword().

Routing Firestore requests through your API might be beneficial if you need to impose rate limits on document updates or other operations.

For server-side rendered web applications, utilizing session cookies is recommended in order to authenticate users before rendering content. This approach involves verifying the cookie using the Admin SDK, fetching any necessary data, and then rendering the page with the authenticated user's information.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error message: "localStorage not defined - Pairing Recoil with Next.js"

I've implemented a localstorage effect following the guidance in the Recoil documentation. However, upon running my application, I encounter a localStorage is not defined error in the browser. Initially, I assumed that this might be executing on the s ...

Pressing the button in JqGrid will assign an identification number

I am facing an issue with selecting rows in my JqGrid, so I found a solution on which suggests that I need an ID for every row. Whenever I add data to my Grid by pressing a button, I tried assigning each row an ID using a simple click counter function. H ...

Prevent users from entering past dates in the date input field

In my project, I have decided to use input type date instead of datepicker. Is there a way to prevent users from selecting back dates in input type date without using datepicker? If you have any suggestions, please let me know. Thank you! ...

Which file from Next.js should I statically serve using Node?

Whenever I work with React, my standard process includes running npm build, moving the content to a directory named public in Node, and then including the following code snippets: node/app.js app.use(express.static(path.join(__dirname, 'public') ...

In search of a highly efficient webservices tutorial that provides comprehensive instructions, yielding successful outcomes

I've reached a point of extreme frustration where I just want to break things, metaphorically speaking, of course. For the past week, I've been trying to learn how to create a web service using C# (whether it's WCF or ASMX, I don't rea ...

What is the reason for sending a single file to the server?

A function called "import File" was developed to send multiple files to the server, but only one file is being received. Input: <input type="files" id="files" name="files" multiple onChange={ (e) => this.importFile(e.target.files) } ...

The expiration time and date for Express Session are being inaccurately configured

I'm experiencing an issue with my express session configuration. I have set the maxAge to be 1 hour from the current time. app.use( session({ secret: 'ASecretValue', saveUninitialized: false, resave: false, cookie: { secure ...

Change the default direction of content scrolling in CSS and JavaScript to scroll upwards instead of

I am currently working on a website where the navigation bar spans the entire width and remains fixed in place. Below the navigation bar is a cover image, followed by the main content section. As you scroll down, the navigation bar covers the image from t ...

Error message: ReactJs is throwing a TypeError due to mod not being recognized as a function

After updating Swiper from version 9.3.2 to 10.2.0, a new issue has arisen in my reactJs project that says TypeError: mod is not a function. ...

Determine the absolute path with respect to a different reference path, rather than the current working directory

One of the challenges I'm facing with my Node.js module is how to easily allow developers to edit the location of the dependencies relative to the module file itself. The issue arises because the current working directory, accessed through `process.cw ...

Filtering data in Asp.net MVC 3 and converting it to JSON format

For my asp.net mvc 3 project, I'm considering the best approach for handling data: should I pass all the data via JSON and filter it with JavaScript, or should I filter the data first and then convert it to JSON? If filtering the data before passing ...

There was a type error that occurred because the property 'addEventListener' could not be read from an undefined value

Encountering an issue with the JavaScript libraries three.js and OrbitControls.js despite following a tutorial: However, an error is being displayed in the console: Uncaught TypeError: Cannot read property 'addEventListener' of undefined at ne ...

What is the best way to create a slideshow using an IFrame?

Currently seeking a solution for an iframe slideshow that can smoothly transition between multiple HTML iframes. I have a total of 5 iframes that need to rotate automatically and continuously. Any suggestions on how to build a lively and dynamic iframe sl ...

Protractor Throws Element Visibility Issue

When attempting to check a checkbox in the UI, I encounter an "ElementNotVisibleError: element not visible" error. Strangely, I am able to successfully capture and click the checkbox using the console in Chrome developer tools. Has anyone else experience ...

Encountered a Next-Auth Error: Unable to fetch data, TypeError: fetch failed within

I've been struggling with a unique issue that I haven't found a solution for in any other forum. My Configuration NextJS: v13.0.3 NextAuth: v4.16.4 npm: v8.19.2 node: v18.12.1 When the Issue Arises This particular error only occurs in the pr ...

Is it possible to preserve the query parameters from the previous page using Vue Router's Navigation guard feature?

Hey there! So, I'm looking to pass a query from the current page to the next one without manually coding it into all of my push functions. I was wondering if there's a way to do this through Navigation guard or some hooks? I did some research an ...

Error occurred during the authentication process while attempting to upload a file to Firebase storage

While attempting to upload a small file to Firebase storage using Vue.js, I keep encountering a QUOTA_EXCEEDED error. It seems there are an unusually high number of calls to https://securetoken.googleapis.com/v1/token?key=<SomeLongString>. Despite th ...

Utilize Moment in React-Native to adjust the time zone format for the Vi Locale

I'm encountering a date formatting issue while using Moment in React-Native. Specifically, I have formatted the date to an English locale, but now I want it to also support the Vietnamese locale: Moment('2022-09-02T02:00:00+00:00') . ...

Best practices for managing an array of buttons and handling click events in ReactJs

While working on my react class component, I encountered an issue. The alert popup keeps appearing constantly without any button click as soon as the component renders. onHandleOnClick(data, e) { console.log(data); alert("got it" + data); } rend ...

"Incorporating splice in a for loop is causing issues and not functioning

I've been attempting to remove an item from an array, but for some reason, it's not working. Here's the code I'm using: vm.Continue = function () { $scope.invalidList = []; if (vm.errorexsist === true) { var table = doc ...