1

I am new to Google Cloud Platform and Flutter and I want to call a function from my flutter project. This GCF computes the Levenshtein distance between two strings and is implemented like:

from flask import jsonify, abort
from Levenshtein import distance as levenshtein_distance, ratio, editops as string_ops_needed

def json_abort(status_code, message):
    data = {
        'error': {
            'code': status_code,
            'message': message
        }
    }
    response = jsonify(data)
    response.status_code = status_code
    abort(response)

def word_distance(request, decoded_token = None):

    """HTTP Cloud Function.
    Args:
        request (flask.Request): The request object.
        <http://flask.pocoo.org/docs/1.0/api/#flask.Request>
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using `make_response`
        <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>.
    """
    request_json = request.get_json(silent=True)
    '''request_args = request.args'''

    if request_json and "candidate_string" in request_json and "correct_string" in request_json:
        candidate_string=request_json["candidate_string"]
        correct_string=request_json["correct_string"]

        distance=levenshtein_distance(candidate_string,correct_string)

        response = jsonify(distance=distance, status_code=200)
        return response
    else:
        json_abort(400, message="Missing params")

When I try to call it from flutter, with the following code Flutter returns Exception has occurred. PlatformException (PlatformException(functionsError, Cloud function failed with exception., {message: Response is not valid JSON object., details: null, code: INTERNAL}))

final HttpsCallable callable = CloudFunctions.instance
        .getHttpsCallable(functionName: 'word_distance')
          ..timeout = const Duration(seconds: 10);

    dynamic result = await callable.call(
      <String, dynamic>{
        "candidate_string": candidateString,
        "correct_string": correctString
      },
    );

When I test the function in GCF with {"candidate_string": "helo worlt", "correct_string": "hello world"}

It returns the result {"distance":2,"status_code":200}

Any idea on why it happens and how to solve this issue? I found this post but it does not show a specific example on how to proceed.

1
  • 1
    Are you able to get a proper response by manually curl-ing the endpoint for your function? Does your function allow unauthenticated invocations? Is there anything in the logs for your function? Commented May 2, 2020 at 19:05

2 Answers 2

2

After having a look at GCF log as suggested by Dustin Ingram, I found that my function was being accessed but the parameters and output where not ok. So after deeply checking this example again, and taking into account Google specs for https.onCall I found out that it is necessary to return a 'data'/'error' json.

I changed my GCF to the following and now it returns the expected value.

from flask import jsonify, abort

from Levenshtein import distance as levenshtein_distance, ratio, editops as string_ops_needed

def word_distance(request):

    """HTTP Cloud Function.
    Args:
        request (flask.Request): The request object.
        <http://flask.pocoo.org/docs/1.0/api/#flask.Request>
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using `make_response`
        <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>.
    """

    request_json = request.json.get('data')

    if "candidate_string" in request_json and "correct_string" in request_json:
        candidate_string=request_json["candidate_string"]
        correct_string=request_json["correct_string"]

        distance=levenshtein_distance(candidate_string,correct_string)

        return jsonify({
            'data': {
                'distance': distance
            }
        })
    else:
        data = {
            'error': {
                'code': 400,
                'message': 'Missing params'
            }
        }
        response = jsonify(data)
        response.status_code = 400
        return(response)
Sign up to request clarification or add additional context in comments.

Comments

0

Well, you are calling the function with a Map argument which I think is causing the error because it can not get parsed into JSON properly.

Try using

<String, dynamic>{
        '"candidate_string"': '"$candidateString"',
        '"correct_string"': '"$correctString"'
      }

I have got this error many times when sending json data via TCP protocol and the above one worked for me, reason being, it can easily parsed into JSON

1 Comment

I tried this approach but it still retrieves the same error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.