How can we resolve firebase functions INTERNAL exception in a flutter app?

Viewed 4776

I am working on a flutter app using firebase firestore and firebase functions.I am getting this exception again and again -

[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: [firebase_functions/internal] INTERNAL
E/flutter (15454): #0      catchPlatformException (package:cloud_functions_platform_interface/src/method_channel/utils/exception.dart:19:3)

I have tried to resolve this exception since last few hours but unable to make any progress. This the code for my function from index.js file.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

    exports.addUser = functions.https.onCall(async (data) => {
        await admin.firestore().collection("collection_name").add({
          name: "my_name",
          email: "my_email" 
        }
        );
    });

This is my dart code for flutter app.

                MyButton(
                  onPressed: () async {
                    HttpsCallable a =
                        FirebaseFunctions.instance.httpsCallable("addUser");
                    final x = await a();
                    print(x.data);  
                  },
                ),

Thanks in advance !

4 Answers

You have to catch errors and rethrow them as functions.https.HttpsError. That's nothing new. Literally, everyone's answer in this thread includes this. Hovewer what's I've recently discovered are special defined requirements for error code of HttpsError.

It appears that it can't be any string, but one of the values of FunctionsErrorCode enum. Possible values are listed here:

"ok" | "cancelled" | "unknown" | "invalid-argument" | "deadline-exceeded" | "not-found" | "already-exists" | "permission-denied" | "resource-exhausted" | "failed-precondition" | "aborted" | "out-of-range" | "unimplemented" | "internal" | "unavailable" | "data-loss" | "unauthenticated"

More on: https://firebase.google.com/docs/reference/functions/common_providers_https#functionserrorcode

Hope it helps someone, though it's not a new question.

I thought you only meant client side. But to recap what Yadu wrote you should handle it in the cloud function as well. Something like this:

exports.addUser = functions.https.onCall(async (data) => {
  try {
    await admin.firestore().collection("collection_name").add({
      name: "my_name",
      email: "my_email" 
    }
    );
  } catch (err) {
    throw new functions.https.HttpsError('invalid-argument', "some message");
  }
});

and on client side:

HttpsCallable a = FirebaseFunctions.instance.httpsCallable("addUser");

try {
  final x = await a();
  print(x.data);  
} on FirebaseFunctionsException catch (e) {
  // Do clever things with e
} catch (e) {
  // Do other things that might be thrown that I have overlooked
}

You can read a bit more about it on https://firebase.google.com/docs/functions/callable#handle_errors

Client side description is available under the section: "Handle errors on the client"

the internal exception is because you are not handling the error in your function, use try catch in your function, wrap your whole logic in try, catch it and rethrow a functions.https.HttpsError which will be handled by firebase accordingly, this is because firebase expects `HttpsError' not any other error which will end up in being Internal error on client side

In case it helps, with a callable firebase function, the message [firebase_functions/internal] INTERNAL message can sometimes mean that you've spelled or capitalized your function name incorrectly in the client code, and it doesn't exactly match the function name on the server.

Or that you've deployed to a non-default region, and your client side code needs to explicitly call to that region. eg.

exports.createUser = functions.region("australia-southeast1").https.onCall( async (data) {...etc})

So the try/catch and all the error checking inside the cloud function means nothing because the function never actually gets called. The error message is very unhelpful!

Related