typescript - Flutter no pudo llamar a la función en la nube invocable con error [firebase_functions/permission-denied] PERMISSION_DENIED
Estoy teniendo este error al intentar llamar a una función invocable desde Flutter:
W/FirebaseContextProvider( 3655): Error getting App Check token. Error: com.google.firebase.FirebaseException: Error returned from API. code: 403 body: App attestation failed.
D/TrafficStats( 3655): tagSocket(294) with statsTag=0xffffffff, statsUid=-1
E/flutter ( 3655): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [firebase_functions/permission-denied] PERMISSION_DENIED
E/flutter ( 3655):
E/flutter ( 3655): #0 StandardMethodCodec.decodeEnvelope
message_codecs.dart:653
E/flutter ( 3655): #1 MethodChannel._invokeMethod
platform_channel.dart:315
E/flutter ( 3655): <asynchronous suspension>
E/flutter ( 3655): #2 MethodChannelHttpsCallable.call
method_channel_https_callable.dart:22
E/flutter ( 3655): <asynchronous suspension>
E/flutter ( 3655): #3 HttpsCallable.call
https_callable.dart:49
E/flutter ( 3655): <asynchronous suspension>
E/flutter ( 3655): #4 _SendFeedbackModalBottomSheetState.build.<anonymous closure>
send_feedback.dart:90
E/flutter ( 3655): <asynchronous suspension>
E/flutter ( 3655):
E/flutter ( 3655): #0 StandardMethodCodec.decodeEnvelope
message_codecs.dart:653
E/flutter ( 3655): #1 MethodChannel._invokeMethod
platform_channel.dart:315
E/flutter ( 3655): <asynchronous suspension>
E/flutter ( 3655): #2 MethodChannelHttpsCallable.call
method_channel_https_callable.dart:22
E/flutter ( 3655): <asynchronous suspension>
E/flutter ( 3655): #3 HttpsCallable.call
https_callable.dart:49
E/flutter ( 3655): <asynchronous suspension>
E/flutter ( 3655): #4 _SendFeedbackModalBottomSheetState.build.<anonymous closure>
send_feedback.dart:90
E/flutter ( 3655): <asynchronous suspension>
E/flutter ( 3655):
Aquí se muestra cómo se llama a la función invocable:
final HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('sendFeedback');
final resp = await callable.call(<String, dynamic>{
'email': '[email ',
'message': message,
});
Así es como se ve la función en la nube:
const sendgridApiKey = functions.config().sendgrid.key;
sgMail.setApiKey(sendgridApiKey);
export const sendFeedback = functions.https.onCall(async (data, context) => {
// Check if the user is authenticated
if (!context.auth) {
throw new functions.https.HttpsError("unauthenticated", "User is not authenticated");
}
const message = data.message;
try {
// Compose the email message
const emailMessage = {
to: "[email ",
from: "[email ",
subject: "Feedback from user",
text: message,
};
// Send the email using SendGrid
await sgMail.send(emailMessage);
return {
success: true, message: "Email sent successfully",
};
} catch (error) {
console.error("Error sending email:", error);
throw new functions.https.HttpsError("internal", "An error occurred while sending the email");
}
});
Esto ocurre en el simulador y en un dispositivo real. He revisado la cuenta de servicio "Cuenta de servicio predeterminada de App Engine" y su rol es "Editor". ¿Hay algo que falte que deba hacer para solucionar ese error de permisos?
Actualización: Intenté usar el token de depuración de App Check hoy según lo indicado en https://firebase.google.com/docs/app-check/flutter/debug-provider#android y ya no vi el error "Error al obtener el token de App Check. Error: com.google.firebase.FirebaseException: Error devuelto por la API. código: 403 cuerpo: Falló la validación de la aplicación". Pero el error de permiso denegado aún ocurrió.
Respuesta #1
Finalmente pude resolver el error agregando el rol Invocador de funciones en la nube con el principal allUsers a la función.