skip to Main Content

There’s something wrong with this function here, that I’cant find the reason for, I’m trying to add new users to my firebase database, and it doesn’t work

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(
                        "Erro interno",
                        "Erro ao criar usuário",
                        error
                    );
                });
        } else {
            throw new functions.https.HttpsError(
                "unauthenticated",
                "Only admins can create users."
            );
        }
    }
);

it should work with these functions

async signUp({ adminEmail, adminPassword, adminNome, role, isActive}: any): Promise<void> {
this.fns
  .httpsCallable('createUserWithEmailAndPassword')({ adminEmail, adminPassword, adminNome, role, isActive }).subscribe({
    next: response => {
      console.log('Usuário criado com sucesso!');
    },
    error: (err: FirebaseError) => {
      console.log(
        `${err.message}: Erro ao cadastrar usuário. Tente novamente.`
      );
    }
  });

}

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)
    )

  }

But there’s something wrong with my firebase function that is stopping the creation, in the console it calls exactly the first function

error in console

enter image description here

So I’ve looked in the logs in firebase

error code: Erro interno.
    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"
}

2

Answers


  1. Chosen as BEST ANSWER

    Well we've managed to find the solution, and I think Renaud kind of pointed in that direction and I've must have missed.

    Since the data was coming but wasn't passing through the try we made a verification first.

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

    then we inserted into the the try so it would pass the verification

    exports.createUserWithEmailAndPassword = functions.https.onCall(
        async (data, context) => {
            try {
                const { adminEmail, adminPassword, adminNome, role, isActive } = data;
                const idUsuario = context.auth.token.uid;
                if (verifyUserAdmin(idUsuario)) {
                    const user = await admin.auth().createUser({
                        email: adminEmail,
                        password: adminPassword,
                        displayName: adminNome
                    });
                    const customClaims = {
                        admin: true
                    };
                    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(
                    "Erro interno",
                    "Erro ao criar usuário",
                    error
                );
            }
        });
    

    And now we can finally add users in our database through the app


  2. You don’t share any error but there are two thing you should adapt:

    1. Avoid mixing then() with async/await.
    2. Declare registeredAt and user.uid as variables.

    Also note that you don’t pass any value for isActive when you call the CF from your front-end.


    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();  // You could use FieldValue.serverTimestamp()  // Add const FieldValue = require('firebase-admin').firestore.FieldValue; at the top of the index.js file
    
                    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(
                    "Erro interno",
                    "Erro ao criar usuário",
                    error
                );
            }
    
        });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search