Search code examples
firebasefluttergoogle-cloud-functions

Unable to use a Callable Cloud Function in Flutter


I'm currently using a Firebase Cloud Function, which I wish I can use on Call to check if an Image has adult content, and see some of the tutorials out there I manage to create this function:

exports.checkImage = functions.https.onCall(async (data, context) => {
    const img_base64 = data;

    const request = {
        image: {
            content: img_base64
        }
    };

    try {
       const [result] = await client2.safeSearchDetection(request);
       console.log(result.safeSearchAnnotation?.adult);
       return result.safeSearchAnnotation?.adult;
    } catch (error) {
        console.log(error);
        return;
    }
    return;
});

Now I'm tried to send the Image using an iOS Emulator with that call Function in 2 ways:

First Option I tried:

1.

exports.checkImage = functions.https.onCall(async (data, context) => {
    const img_base64 = data;

    const request = {
        image: {
            content: img_base64
        }
    };

    try {
       const [result] = await client2.safeSearchDetection(request);
       console.log(result.safeSearchAnnotation?.adult);
       return result.safeSearchAnnotation?.adult;
    } catch (error) {
        console.log(error);
        return;
    }
    return;
});

The problem here is I get this Error on my Debugging Console:

[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: MissingPluginException(No implementation found for method FirebaseFunctions#call on channel plugins.flutter.io/firebase_functions)
#0      convertPlatformException (package:cloud_functions_platform_interface/src/method_channel/utils/exception.dart:16:5)
#1      MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:39:13)
<asynchronous suspension>
#2      HttpsCallable.call (package:cloud_functions/src/https_callable.dart:35:37)
<asynchronous suspension>
#3      DatabaseMethods.clearImage
package:property1/providers/database.dart:294
  1. In someplace I read that the onCall Cloud Functions can be use as regular End Points so I did this:

     clearImage(imageX) async {
    
     final url = Uri.parse(
       'https://us-central1-XXXXXXX-XXXX.cloudfunctions.net/checkImage',
     );
    
     try {
     final response = await http.post(
         url,
         body: json.encode({
           "image": {
           "content": imageX
         }),
       );
     }
       }
    

    In this one, I only get an Invalid Request unable to process.

    I even try this from Postman getting the same result bad request.

    As additional data I call this function from where I select the Image with this code:

     void _pickImage() async {
         final imagePicker = ImagePicker();
         final pickedImageFile = await imagePicker.getImage(
           source: ImageSource.gallery,
           imageQuality: 50,
         );
         setState(() {
           if (pickedImageFile != null) {
             _pickedImage = File(pickedImageFile.path);
           }
         });
    
         // This section will be used to check the Images with Google Vision.
         List<int> imageBytes = _pickedImage.readAsBytesSync();
         String base64Image = base64Encode(imageBytes);
    
         DatabaseMethods().clearImage(base64Image);
    
         widget.imagePickFn(File(pickedImageFile.path));
       }
    

Basically, I convert the image to a Base64 encoded image that I send so Cloud Vision could work with it.

I even try to just check if I get to the Cloud Function by Commenting out the try of Cloudvision and just adding a console log to get what data is receiving but it is never reached, always an Invalid request, unable to process is what I get.

Any ideas on why I'm not reaching the Function, or on how I can test this from my iOS Emulator.

Kind Regards,


Solution

  • For calling onCall cloud functions from flutter apps, you have to use FirebaseFunctions.instance.httpsCallable():

    import 'package:cloud_functions/cloud_functions.dart';
    
    try {
      final result =
          await FirebaseFunctions.instance.httpsCallable('checkImage').call();
    } on FirebaseFunctionsException catch (error) {
      print(error.code);
      print(error.details);
      print(error.message);
    }
    

    First, install the package:

    flutter pub add cloud_functions
    

    Here's the documentation.