flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

🐛 cloud_functions Incorrect error for missing function: Response is not valid JSON object

Open jt274 opened this issue 1 year ago • 10 comments

Bug report

When calling a function that cannot be found, the following error message is given:

[firebase_functions/internal] Response is not valid JSON object.

This function was previously working, but is now receiving this error after upgrading to cloud functions 2nd gen. If the function name is replaced with any random string (a certainly non-existent function), the same error is received. I have verified the function is not called in the function logs in cloud console.

The 2nd gen function is in a separate source package v2 from 1st gen functions v1, according to these instructions: https://firebase.google.com/docs/functions/organize-functions#managing_multiple_source_packages_monorepo

Steps to reproduce

Steps to reproduce the behavior:

  1. Update function to 2nd gen in separate source package.
  2. Run function.

Expected behavior

An error message saying that the function is not found or invalid should be shown.

Sample project

    final HttpsCallable cloud = FirebaseFunctions.instance.httpsCallable(
        'search',
        options: HttpsCallableOptions(timeout: Duration(seconds: 30)));
    await cloud.call(<String, dynamic>{
      'type': 'find',
      'query': query,
    }).then((result) {
      //Do things
    }).catchError((error) {
      print('ERROR RUNNING FUNCTION: $error');
    });

Additional context

The function still does not call with the following function names: v2-search v2.search v2:search https://search-xxxxxxxxxx-uc.a.run.app.


Flutter doctor

Click To Expand
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.0.5, on Microsoft Windows [Version 10.0.19044.1826], locale en-US)
[!] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    X cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    X Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/windows#android-setup for more details.
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.10.0)
[√] Android Studio (version 2021.2)
[!] Android Studio (version 2021.2)
    X Unable to determine bundled Java version.
[√] VS Code (version 1.69.2)
[√] Connected device (4 available)
[√] HTTP Host Availability

! Doctor found issues in 2 categories.

Flutter dependencies

Click To Expand
cloud_functions: ^3.3.3
firebase_auth: ^3.6.1
firebase_core: ^1.20.0

jt274 avatar Aug 01 '22 19:08 jt274

Thanks for the report @jt274 Please take a look at this document and see if, since the v2 version of the plugin is in beta public preview, you might be seeing this error.

  1. Update function to 2nd gen in separate source package.

Can you provide how to do this ?

Also, looking at context of the issue, this might belong to native SDK and not at client side, as FlutterFire plugins are wrappers around native sdks.

darshankawar avatar Aug 02 '22 10:08 darshankawar

@darshankawar As linked to in the original post, I organized v1/v2 functions into separate folders according to this: https://firebase.google.com/docs/functions/organize-functions#managing_multiple_source_packages_monorepo

I did this because I could not manage to deploy an individual v2 function in the same folder.

I copied the original v1 function into the v2 folder and changed this:

import * as functions from 'firebase-functions';
exports.search = functions.https.onCall(async (data, context) => { });

To this:

import { onCall } from 'firebase-functions/v2/https';
exports.search = onCall(async (request) => { });

jt274 avatar Aug 02 '22 16:08 jt274

Thanks for the update. Can you provide the entire error log ? Also, please check if this helps in your case.

darshankawar avatar Aug 03 '22 06:08 darshankawar

@darshankawar I'd already come across that post, and specifying the region does not make a difference. The function is already in the us-central1 region. The only error provided is the error I included above. But it is clear to me the function is not being called.

According to this reference: https://firebase.google.com/docs/functions/beta/callable

You must use the full URL to call the function since v2 does not yet support cloudfunctions.net URLs. I have tried the full URL and it gives the same error. At the link above, it only shows examples for the Web and Swift/Kotlin SDKs. It appears that v2 callable functions are currently not supported in the Flutter SDK. For the time being, I will need to use a regular HTTP request and include the Authorization header.

jt274 avatar Aug 03 '22 16:08 jt274

I'm using my v2 functions in the same package as my v1 functions and still I get this error on flutter.

I/flutter (12830): [firebase_functions/internal] Response is not valid JSON object.

I'm using:

cloud_functions: 3.3.3

The code works with the same function which is written in v1.

This is how I'm calling the function:

      HttpsCallable callable = FirebaseFunctions.instance
          .httpsCallable("functionnamev2");

      dynamic response = await callable.call(<String, dynamic>{
        "id": id,
        "hours": 40,
        "score": 10
      });

This is how the function is written:

const {onCall, onRequest} = require('firebase-functions/v2/https');

/// The flutter code works with this one
exports.functionNameV1 = functions.runWith(functionNameV1RuntimeOpts).https.onCall(async (req, context) => {

    if (!context.auth) {
        return {status: 'error', code: 401, message: 'Not signed in'}
    }

    const {
        functionNameHelper
    } = require("./helpers/generalHelpers/functionNameHelper");
    return await functionNameHelper(req, admin);
});

/// The flutter code doesn't work with this one
exports.functionnamev2 = onCall(functionnamev2runtimeopts,async (req, context) => {

    if (!context.auth) {
        return {status: 'error', code: 401, message: 'Not signed in'}
    }

    const {
        functionNameHelper
    } = require("./helpers/generalHelpers/functionNameHelper");
    return await functionNameHelper(req, admin);
});

I also used the full v2 function url something like this:

https://functionnamev2-something-uc.a.run.app
or
functionnamev2-something-uc.a.run.app

Still getting the same error.

Does cloud_functions plugin support v2 functions?

lvlrSajjad avatar Aug 05 '22 12:08 lvlrSajjad

Does cloud_functions plugin support v2 functions?

It appears it currently does not support v2 functions. You must call the function with the full URL using a regular HTTP request (using dart http package), and include the Authorization header if using firebase auth. I have done this successfully.

I've also separately discovered v2 functions cannot connect to a Cloud SQL instance. It seems that the current v2 beta preview is not very useful yet.

jt274 avatar Aug 05 '22 17:08 jt274

as I see the problem with cloud_functions not cloud_firestore ..

I simply don't use cloud_functions, I use simple http requests instead, and trigger the function by calling it's triggerable URL..

by making POST request and provide whatever parameters I want ..

it's suggestion , works perfect for me, and this is what the plugin do in general ...

thx

imeDevelopers avatar Aug 06 '22 16:08 imeDevelopers

It seems that the current v2 beta preview is not very useful yet.

Considering this and as also shared the same as part of this document from Firebase, the issue doesn't seem to be at client side due to current limitation. I advise you to reach out to Firebase support for further resolution.

darshankawar avatar Aug 09 '22 08:08 darshankawar

@darshankawar I do believe the original bug report is still valid though, for the cloud_functions package. When a function is not found, it should provide an error message that says the function is not found. The same error received when trying to call a v2 function, is received when putting in a random string of characters for the function name.

It currently returns: [firebase_functions/internal] Response is not valid JSON object.

But it should return something like: [firebase_functions/invalid] Function not found.

jt274 avatar Aug 09 '22 15:08 jt274

Thanks for the update. Keeping this issue open for further insights from the team.

darshankawar avatar Aug 10 '22 06:08 darshankawar

I'm also getting an error when calling a v2 function. v1 works perfectly fine, but when calling a v2 function, I get:

[firebase_functions/-1004] Could not connect to the server.

Yes, the region is correct, and ingress is set to "ALLOW_ALL". When I paste the function url into a webbrowser it shows up in the logs as "wrong method GET" along with complaints about missing parameters. This does not happen for a function called via the cloud_functions: ^4.0.6 package.

Also, when calling .useFunctionsEmulator("0.0.0.0", 5001) before, it also works perfectly.

ciriousjoker avatar Jan 02 '23 21:01 ciriousjoker

In case someone else struggles with this, here's the code snippet I'm using, now it works:

import 'package:deep_pick/deep_pick.dart';

...

  final data = jsonEncode({
    "data": {
      "goals": goals,
      "trainingplans": trainingplans,
      "skills": skills,
    }
  });

  final response = await http.post(
    Uri.parse("https:/...-...-ew.a.run.app"),
    headers: {
      "Content-Type": "application/json",
    },
    body: data,
  );
  final result = jsonDecode(response.body)["result"];

ciriousjoker avatar Jan 02 '23 22:01 ciriousjoker

We support v2 functions since https://pub.dev/packages/cloud_functions/versions/4.1.0, I'll close this issue. Feel free to open a new one if your issue is still not solved.

Lyokone avatar Nov 24 '23 10:11 Lyokone