FlutterFlow / flutterflow-issues

A community issue tracker for FlutterFlow.
120 stars 18 forks source link

API calls with Multipart body do not work when Streaming Responses turned on #3450

Open sgardoll opened 2 months ago

sgardoll commented 2 months ago

Can we access your project?

Current Behavior

When making an API call that needs to include a Multipart body (due to needing to include a file buffer, for example), these calls fail and do not go through to the API if "Process Streaming Responses" is turned on in Advanced Settings

Expected Behavior

the call should successfully reach the designated API endpoint and process the request without any issues, regardless of whether the “Process Streaming Responses” option is turned on or off in Advanced Settings.

Specifically, the expected behavior is as follows:

1.  The API call with a Multipart body is initiated from a user interaction.
2.  The request, including the file buffer and any other necessary parameters, is correctly formatted and sent to the API endpoint.
3.  The API endpoint receives the request and processes it as intended, returning the appropriate response.
4.  The FlutterFlow application receives the response and handles it according to the defined logic, whether “Process Streaming Responses” is enabled or disabled in Advanced Settings.

Steps to Reproduce

1.  Create a New FlutterFlow Project:
•   Start a new project in FlutterFlow or open an existing one.

2.  Set Up the API Call:
•   Define an API call that requires a Multipart body. Ensure the API endpoint is set up to receive and process a file buffer.

3.  Create a Page with Two Buttons:
•   Add a new page to your FlutterFlow project.
•   On this page, add two buttons: “Button A” and “Button B”.

4.  Add File Upload Action:
•   Set up the Action Flow to include a file upload step before the API call is made.
•   Ensure that the file to be uploaded is selected and its data is available for the API call.

5.  Configure Button A (Streaming Responses ON):
•   Set up “Button A” to trigger the API call with the Multipart body, including the uploaded file.
•   Enable “Process Streaming Responses” in the Advanced Settings for this API call.

6.  Configure Button B (Streaming Responses OFF):
•   Set up “Button B” to trigger the same API call with the Multipart body, including the uploaded file.
•   Disable “Process Streaming Responses” in the Advanced Settings for this API call.

7.  Test the API Calls:
•   Run the project and navigate to the page with the two buttons.
•   Click “Button A” to initiate the file upload and API call with “Process Streaming Responses” enabled.
•   Observe the behavior and whether the API call succeeds or fails.
•   Click “Button B” to initiate the file upload and API call with “Process Streaming Responses” disabled.
•   Observe the behavior and whether the API call succeeds or fails.

Reproducible from Blank

Bug Report Code (Required)

IT4WhvHlx5NPvt9A1s+MbfpagioUKUR/UIJI0sN+ewkYIbLtO4wPXfikSEpWZ9+kTHxcL2ajuGUK+dKPhtnMA+UqYE2rGrZ8yLhhFguXeHmgVq6gDKmWPUR9J+JJJVOByrbQgSYnBM52WHwM1zmuC+6tEz3aJqbMNjMwRv7/EK3PgXOqQ0SLb3kNh1JWeC/v

Visual documentation

You can clone project here: https://app.flutterflow.io/project/reception-assistant-fjjxly

Video/jam: https://jam.dev/c/4215019a-bacb-4587-b3c7-ee0bf77f52e8

Environment

- FlutterFlow version: 4.1.74
- Platform: Mac OS 14.5 (23F79)
- Browser name and version: Chrome
- Operating system and version affected: 14.5 (23F79)

Additional Information

No response

Alezanello commented 2 months ago

Hello!

Thank you for sharing your project. I cloned it and was able to compile it. However, it seems that the voice never ends, or something is missing to complete the sending of the voice to the API. I don't see any error logs or indications of what might be preventing it from sending.

Do you know if this Buildship endpoint supports SSE or Websockets?

Best regards,
Azanello

sgardoll commented 2 months ago

Hi there, BuildShip supports both, but this endpoint is anticipating an SSE response.

The issue is that it never gets to the BuildShip endpoint.

Can I suggest you delete the button for the standard API call and leave only the Streaming button and call. Then Local Run with the Dev Logs open and you'll see the API call just never makes it out of Flutterflow. There aren't ever any logs that show up on the BuildShip side either.

Happy to share access to the BuildShip endpoint with you if it helps?

Thanks, Stuart

On Mon, 22 July 2024, 11:09 pm Alezanello, @.***> wrote:

Hello!

Thank you for sharing your project. I cloned it and was able to compile it. However, it seems that the voice never ends, or something is missing to complete the sending of the voice to the API. I don't see any error logs or indications of what might be preventing it from sending.

Do you know if this Buildship endpoint supports SSE or Websockets?

Best regards, Azanello

— Reply to this email directly, view it on GitHub https://github.com/FlutterFlow/flutterflow-issues/issues/3450#issuecomment-2242920860, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARMHLAZLK5QFLNFARHAUKKDZNT777AVCNFSM6AAAAABLHSP2SWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBSHEZDAOBWGA . You are receiving this because you authored the thread.Message ID: @.***>

sgardoll commented 2 months ago

Anything else I can help with to push this one along @leighajarett @Alezanello ?

Alezanello commented 2 months ago

Hello!

Sorry for the late response. The engineering team is already looking into this and working on a fix!

Thank you for bringing this to our attention!

Best regards,
Azanello

github-actions[bot] commented 2 months ago

This issue is stale because it has been open for 7 days with no activity. If there are no further updates, a team member will close the issue.

thiwa8 commented 1 month ago

I have the same problem. The precise error thrown by flutterflow is

Error: NoSuchMethodError: method not found: 'charCodeAt' (a.charCodeAt is not a function)"

vrushal007 commented 2 weeks ago

@sgardoll I have got this issue resolved. They have written condition like: if request is streaming and another if condition is like is bodytype is multipart.

I guess they haven't written this condition in current auto generated code

// Auto generated code of flutterflow of api_manager.dart

    if (isStreamingApi) {
      // logic of flutterflow
    }

    if (bodyType == BodyType.MULTIPART) {
       // logic of flutterflow
    }

I have added one more condition below isStreamingApi condition in api_manager.dart

if (bodyType == BodyType.MULTIPART && isStreamingApi) {
      // If it's a streaming API with multipart, handle accordingly
      client ??= http.Client();

      bool isFile(dynamic e) => e is FFUploadedFile || e is List<FFUploadedFile> || (e is List && e.firstOrNull is FFUploadedFile);

      final nonFileParams = toStringMap(Map.fromEntries(params.entries.where((e) => !isFile(e.value))));

      List<http.MultipartFile> files = [];
      params.entries.where((e) => isFile(e.value)).forEach((e) {
        final param = e.value;
        final uploadedFiles = param is List ? param as List<FFUploadedFile> : [param as FFUploadedFile];
        for (var uploadedFile in uploadedFiles) {
          files.add(
            http.MultipartFile.fromBytes(
              e.key,
              uploadedFile.bytes ?? Uint8List.fromList([]),
              filename: uploadedFile.name,
              contentType: _getMediaType(uploadedFile.name),
            ),
          );
        }
      });

      final request = http.MultipartRequest(type.toString().split('.').last, Uri.parse(apiUrl))
        ..headers.addAll(toStringMap(headers))
        ..files.addAll(files);
      nonFileParams.forEach((key, value) => request.fields[key] = value);

      final streamedResponse = await getStreamedResponseWithMultipartRequest(request);
      return ApiCallResponse(
        null,
        streamedResponse.headers,
        streamedResponse.statusCode,
        streamedResponse: streamedResponse,
      );
    }

// get_streamed_response.dart //add below method Future getStreamedResponseWithMultipartRequest(MultipartRequest request) => Client().send(request);

Disclaimer : It may contain some redundant code. but it works for me. If issue still persists then let me know if I can help you.