Issues encountered when attempting to add a new user on Firebase

I am facing an issue with this function that is supposed to add new users to my firebase database, but for some reason, it's not working.

exports.createUserWithEmailAndPassword = functions.https.onCall(
    async(data, context) => {
        const { adminEmail, adminPassword, adminNome, role, isActive } = data;

        if (context.auth.token.roles.includes("admin")) {
            const user = await admin.auth().createUser({
                email: adminEmail,
                password: adminPassword,
                displayName: adminNome
            });
            const customClaims = {
                roles: [role],
            };
            await admin.auth().setCustomUserClaims(user.uid, customClaims)
            await db.collection("admin-roles").doc(user.uid).set({
                    uid: user.uid,
                    adminEmail,
                    adminPassword,
                    adminNome,
                    role,
                    isActive: true,
                    registeredAt: Date.now()
                }, { merge: true })
                .then(() => {
                    console.log(
                        `User "${adminNome}" created. Custom claim added: "${customClaims.roles}"`
                    );
                    return {
                        uid,
                        adminEmail,
                        adminPassword,
                        adminNome,
                        role,
                        isActive,
                        registeredAt
                    };
                })
                .catch((error) => {
                    throw new functions.https.HttpsError(
                        "Internal Error",
                        "Error creating user",
                        error
                    );
                });
        } else {
            throw new functions.https.HttpsError(
                "unauthenticated",
                "Only admins can create users."
            );
        }
    }
);

This function should work in conjunction with the following ones:

async signUp({ adminEmail, adminPassword, adminNome, role, isActive}: any): Promise<void> {
this.fns
  .httpsCallable('createUserWithEmailAndPassword')({ adminEmail, adminPassword, adminNome, role, isActive }).subscribe({
    next: response => {
      console.log('User created successfully!');
    },
    error: (err: FirebaseError) => {
      console.log(
        `${err.message}: Error while registering user. Please try again.`
      );
    }
  });

}

signUp() {
    this.adminNovo.adminPassword = ''

    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (var i = 0; i < 9; i++) {
      this.adminNovo.adminPassword += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    console.log(this.adminNovo)
    this.adminService.signUp(this.adminNovo).then(
      (res: any) => console.log(res)
    )

  }

However, there seems to be an issue with my firebase function preventing the creation of users. In the console, it exactly calls the first function.

Error in console

https://i.stack.imgur.com/FJKOW.png

Therefore, I checked the logs in firebase and found this:

Error code: Internal Error.
    at new HttpsError (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:69:19)
    at /workspace/index.js:89:19
    at fixedLen (/workspace/node_modules/firebase-functions/lib/providers/https.js:66:41)
    at /workspace/node_modules/firebase-functions/lib/common/providers/https.js:385:32
    at processTicksAndRejections (node:internal/process/task_queues:96:5)


{
insertId: "6329b7680004d257cbcc04fa"
labels: {
execution_id: "xss82uddvcsm"
instance_id: "00c61b117c54f94608670deae52421503ae18f031859611f1e55f4b3ec13c0990192a31900a81fb99db4d03e7cf36203f4726c29cb6acb0f1545"
}
logName: "projects/dev-processo-seletivo/logs/cloudfunctions.googleapis.com%2Fcloud-functions"
receiveTimestamp: "2022-09-20T12:51:52.643048282Z"
resource: {
labels: {3}
type: "cloud_function"
}
severity: "ERROR"
textPayload: "Invalid request, unable to process."
timestamp: "2022-09-20T12:51:52.315991Z"
trace: "projects/dev-processo-seletivo/traces/f3e3336110816f1a5e7dfc609827f649"
}

Answer №1

There doesn't seem to be any errors present, however there are a couple of things you might want to consider:

  1. Avoid mixing then() with async/await.
  2. Make sure to declare registeredAt and user.uid as variables.

Additionally, it's important to note that when calling the CF from your front-end, ensure that you provide a value for isActive.


exports.createUserWithEmailAndPassword = functions.https.onCall(
    async (data, context) => {
        try {
            const { adminEmail, adminPassword, adminNome, role, isActive } = data;

            if (context.auth.token.roles.includes("admin")) {
                const user = await admin.auth().createUser({
                    email: adminEmail,
                    password: adminPassword,
                    displayName: adminNome
                });
                const customClaims = {
                    roles: [role],
                };

                const userId = user.uid;

                await admin.auth().setCustomUserClaims(userId, customClaims);

                const registeredAt = Date.now();  

                await db.collection("admin-roles").doc(user.uid).set({
                    uid: userId,
                    adminEmail,
                    adminPassword,
                    adminNome,
                    role,
                    isActive: true,
                    registeredAt
                }, { merge: true });

                console.log(`User "${adminNome}" created. Custom claim added: "${customClaims.roles}"`);

                return {
                    uid: userId,
                    adminEmail,
                    adminPassword,
                    adminNome,
                    role,
                    isActive: true,
                    registeredAt
                };

            } else {
                throw new functions.https.HttpsError(
                    "unauthenticated",
                    "Only admins can create users."
                );
            }
        } catch (error) {
            throw new functions.https.HttpsError(
                "Internal error",
                "Error creating user",
                error
            );
        }

    });

Answer №2

We have successfully found the solution, thanks to Renaud's guidance that I initially overlooked.

After realizing that the data was not passing through as expected, we decided to implement a verification process.

async function verifyUserAdmin(uid) {
    const result = await db.collection('admin-roles').doc(uid).get();
    const user = result.data();
    return user.role.includes("admin");
}

Subsequently, we integrated this verification step into our code to ensure its validity.

exports.createUserWithEmailAndPassword = functions.https.onCall(
    async (data, context) => {
        try {
            const { adminEmail, adminPassword, adminName, role, isActive } = data;
            const userId = context.auth.token.uid;
            if (verifyUserAdmin(userId)) {
                const user = await admin.auth().createUser({
                    email: adminEmail,
                    password: adminPassword,
                    displayName: adminName
                });
                const customClaims = {
                    admin: true
                };
                const generatedUserId = user.uid;
                await admin.auth().setCustomUserClaims(generatedUserId, customClaims);
                const registeredAt = Date.now();
                await db.collection("admin-roles").doc(user.uid).set({
                    uid: generatedUserId,
                    adminEmail,
                    adminPassword,
                    adminName,
                    role,
                    isActive: true,
                    registeredAt
                }, { merge: true });
                console.log(`User "${adminName}" created with custom claim: "${customClaims.roles}"`);
                return {
                    uid: generatedUserId,
                    adminEmail,
                    adminPassword,
                    adminName,
                    role,
                    isActive: true,
                    registeredAt
                };
            } else {
                throw new functions.https.HttpsError(
                    "unauthenticated",
                    "Only admins are allowed to create users."
                );
            }
        } catch (error) {
            throw new functions.https.HttpsError(
                "Internal error",
                "Error creating user",
                error
            );
        }
    });

With these modifications, users can now be added to our database directly from the application.

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

Restoring a mongo database in chai mocha: step-by-step guide

Before starting the tests, I need to restore the mongo database. Here's how I do it: const app = require("../app"); const chai = require("chai"); const mongoose = require("mongoose"); const User = require('../models/users'); const Region = ...

Is there a way to establish a connection with a secondary Firestore database in Node.js, allowing for the use of multiple Firestore databases

I have set up multiple firestore databases within my project. Using the command line, I created these databases and can view them in the Firestore Databases preview by following the instructions outlined here: https://cloud.google.com/blog/products/databas ...

Element not producing output via Autocomplete from mui/material package

My challenge involves handling an array of states within the Autocomplete component. Once a state is selected, a corresponding component needs to be rendered based on the selection. However, despite successful state selection in the code, nothing is being ...

Exploring the challenges of setting up Node in an attempt to unravel AngularJs 1.5

I recently started reading a book called "Unraveling AngularJS 1.5" in order to expand my knowledge on Angular development. Early on in the book, the author suggests installing Node.js, so I went ahead and did that. When I ran Node on the command prompt, i ...

What is the reason browsers do not store JWT tokens in the same manner as they do cookies?

Understanding the distinctions between a cookie and a JSON web token is crucial. With cookies, when the server includes 'set-cookie' in its response header, the browser automatically stores the cookie in local storage. Then, whenever the cookie i ...

Issue encountered while executing `gatsby build` with Kentico Kontent

I have been developing a project that utilizes both Gatsby and Kentico Kontent. During development on my Windows 10 machine, I have had success running gatsby develop and npm run develop. Typically, the output looks like this: $ npm run develop success o ...

What allows the execution of "T[keyof T] extends Function" in TypeScript specifically for Strings?

Lately, I've been experimenting with type changes and I find myself puzzled when encountering code like the following: type DeepReadonly<T> = { readonly [k in keyof T]: T[k] extends Function?T[k]:DeepReadonly<T[k]> } // Let's defin ...

There is no catching Firebase's sneaky Error (auth/internal-error) sneaking around

My current project involves using React js in combination with Firebase authentication to verify users on a web application. I am utilizing the createUserWithEmailAndPassword and signInWithEmailAndPassword functions for user creation/sign-in, as well as th ...

Mastering the utilization of API routes within the Next JS 13 App Router framework

As a newcomer to React JS and Next.js, I recently made the switch from using the Page Router API in Next.js to utilizing the new App Router introduced in Next.js 13. Previously, with the Page Router, creating a single GET request involved nesting your "JS ...

Error: Incorrect data type found in React Route component

I've encountered an issue while attempting to utilize the Route component in my application. The error message I'm receiving reads as follows: [ts] Type '{ path: "/:shortname"; component: typeof FirstComponent; }' is not assignable ...

Reduce the noise from different versions by utilizing package-lock.json

There may not be a clear-cut answer, but I'm curious to hear how others handle the issue of package-lock.json causing problems when committing to their node repository. Many opinions lean towards committing package-lock.json - ensuring consistent dep ...

The import component path in Angular 4/TypeScript is not being recognized, even though it appears to be valid and functional

I'm currently working on building a router component using Angular and TypeScript. Check out my project structure below: https://i.stack.imgur.com/h2Y9k.png Let's delve into the landingPageComponent. From the image, you can see that the path ...

Dealing with the HTTP 413 Request Entity Too Large error within a Node JS Project on Google App Engine

My backend app is currently deployed on GAE. One of the features it offers is an API that allows users to upload files to a GCS bucket. I recently encountered an issue when trying to upload a file larger than 50mb, receiving an error message stating 413 Re ...

Script to automatically execute NPM if it is not included in your system's PATH variable

Unfortunately, I have a restriction that prevents me from adding NPM to my PATH variable. In order to overcome this limitation, I have created a bash script #!/bin/bash shopt -s expand_aliases alias npm-exec='PATH=$(npm bin):$PATH' npm-exec npm ...

Developing React components with Typescript requires careful consideration when defining component props, especially when the component may be

Consider the following scenario: { this.props.userName && <UserProfile userName={this.props.userName} /> In the UserProfile component: interface UserProfileProps { userName: string; } class UserProfile extends React.Component<UserProfile ...

Establish a connection to the ActiveMQ broker utilizing STOMP protocol in an Ionic application

I've recently received an Ionic + Capacitor app that is primarily meant to run on the Android platform. My current task is to incorporate communication with a remote ActiveMQ broker into the app. To achieve this, I utilized the STOMP JS library which ...

Steps for transitioning a VUE JS project to TypeScript

Is it possible to transition a VUE JS project from JavaScript to TypeScript without rewriting everything? I heard from a friend that it can be done through the VUE CLI, but I haven't been able to find any documentation or articles on this method. Has ...

Is there a way to pass a hyperlink as a parameter in Express?

I am attempting to pass a hyperlink (like: "") as a parameter to my Express server script. The current setup of my script is as follows: var app = require("express")(); app.get("/new/:link(*)", function(req, res){ var link = req.params.link; res. ...

The npx documentation explicitly states that in order to avoid any conflicts, it is essential to configure all flags and options before specifying any positional arguments. But what exactly does this directive entail?

The official npx documentation explains the differences between using npx and npm exec. npx vs npm exec When utilizing the npx binary, it is crucial to set all flags and options before including any positional arguments. On the other hand, if you run it v ...

Angular functions are executed twice upon being invoked within the html file

I decided to kick-start an Angular project, and I began by creating a simple component. However, I encountered a perplexing issue. Every time I call a function in the HTML file from the TypeScript file, it runs twice. TS: import { Component, OnInit } from ...