Búsqueda de sitios web

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.