Recently while working on a project using NextJS and Firebase, I ran into a particular problem related new user creation on the firebase platform. I will share more on the project in a future articles.
The problem
On the web app, administrators must be able to set up user accounts with just an email and a name; the password is generated automatically, and the user is sent a reset password email.
On Firebase, the only way to accomplish this is to use the Auth module's createEmailPasswordAccount
method. The issue is that as soon as a user is created, the SDK automatically logs in that user and updates the local auth
instance.
Possible Solutions
One solution would be to create an additional instance of the firebase object on the client, use it to create the new account, logout, and then destroy the instance. The issue with this solution is that Firebase does not support multiple instances running concurrently on the same client, and will throw a runtime error.
Another approach would be to use a cloud function, specifically a Cloud Firestore trigger, to handle the creation of the user account when a document is added to the Firestore. The problem with this solution is that it requires splitting the app into two projects and maintaining both.
What I did
The solution I came up with is to use an API route to handle user creation. The front end component handles all form validation logic and calls the API with the entered credentials.
The API route validates the request, generates the password and creates the account with a Firebase instance before logging out, clearing the instance, and returning the appropriate response to the component.
As an added security measure, I also supply and validate the Firebase authentication token available on the front end. Additionally, NextJS API routes are same-origin only by default, so there’s no need to worry about external requests.
Why it works
I was able to mitigate both problems with the other potential solutions thanks to the advatages of using NextJS.
The first advantage is the separation of server and client side instances, which allowed my server side Firebase instance to handle user creation without interfering with the client.
The second advantage is the ability to write server and client code in the same code base, which reduces cost of maintenance and code duplication.
Conclusion
In summary, the flexibility of nextjs allows you to run multiple instances of firebase in the same app if necessary using server-side API routes.
This can be taken a step further by running the firebase-admin sdk on the server without security risks, because no server side code is shipped to the client and the API routes are protected by NextJS's same-origin only access.