FlutterFlow / flutterflow-issues

A community issue tracker for FlutterFlow.
115 stars 19 forks source link

Converting to DataType from API call raises Converting object to an encodable object failed: Instance of '_JsonDocumentReference' #3433

Closed nicolas-gervais-42 closed 3 weeks ago

nicolas-gervais-42 commented 1 month ago

Can we access your project?

Current Behavior

Issue appeared after July 3rd, last time I deployed and issue does not appear in production

I have an address page where user can type into a textfield that triggers Algolia api call. Call response goes through an interceptor cause I want to return as DataType AlgoliaAddress. The datatype has field which are also Datatype containing doc reference as property. For example

I am using Firestore as DB

Datatype AlgoliaAddress has field ClientRecord which contains name, id and doc reference. Datatype Algolia Address also has field company and path which are also doc reference

The current behavior now raises this error

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ dart_sdk.js:37972 The following JsonUnsupportedObjectError was thrown building FutureBuilder<ApiCallResponse>(dirty, dart_sdk.js:37972 state: _FutureBuilderState<ApiCallResponse>#b89b3): dart_sdk.js:37972 Converting object to an encodable object failed: Instance of '_JsonDocumentReference' dart_sdk.js:37972 dart_sdk.js:37972 The relevant error-causing widget was: dart_sdk.js:37972 FutureBuilder<ApiCallResponse> dart_sdk.js:37972 FutureBuilder:file:///tmp/ff_service_scratch/HHI5Q0lfEDQg7BvgjVLx/yoost/lib/addresses/addresses/addresses_widget.dart:469:43 dart_sdk.js:37972 dart_sdk.js:37972 When the exception was thrown, this was the stack: dart_sdk.js:37972 dart:sdk_internal 11994:11 throw_ dart_sdk.js:37972 dart:sdk_internal 54769:21 writeObject dart_sdk.js:37972 dart:sdk_internal 54842:14 writeMap dart_sdk.js:37972 dart:sdk_internal 54800:28 writeJsonValue dart_sdk.js:37972 dart:sdk_internal 54758:16 writeObject dart_sdk.js:37972 dart:sdk_internal 54810:14 writeList dart_sdk.js:37972 dart:sdk_internal 54795:14 writeJsonValue dart_sdk.js:37972 dart:sdk_internal 54758:16 writeObject dart_sdk.js:37972 dart:sdk_internal 55021:19 printOn dart_sdk.js:37972 dart:sdk_internal 55011:38 stringify dart_sdk.js:37972 dart:sdk_internal 54410:45 convert dart_sdk.js:37972 dart:sdk_internal 54350:52 encode dart_sdk.js:37972 dart:sdk_internal 56816:25 jsonEncode dart_sdk.js:37972 packages/yoost/backend/api_requests/api_manager.dart.js 530:107 get bodyText dart_sdk.js:37972 packages/yoost/auth/firebase_auth/firebase_auth_manager.dart.js 22924:225 <fn> dart_sdk.js:37972 packages/flutter/src/widgets/widget_state.dart.js 76735:86 build dart_sdk.js:37972 packages/flutter/src/widgets/widget_state.dart.js 193189:25 build dart_sdk.js:37972 packages/flutter/src/widgets/widget_state.dart.js 144412:22 performRebuild dart_sdk.js:37972 packages/flutter/src/widgets/widget_state.dart.js 193223:13 performRebuild dart_sdk.js:37972 packages/flutter/src/widgets/widget_state.dart.js 53952:14 rebuild dart_sdk.js:37972 packages/flutter/src/widgets/widget_state.dart.js 192673:21 buildScope dart_sdk.js:37972 packages/flutter/src/widgets/widget_state.dart.js 197910:43 drawFrame dart_sdk.js:37972 packages/flutter/src/widgets/widget_state.dart.js 102539:12 [_handlePersistentFrameCallback] dart_sdk.js:37972 packages/flutter/src/scheduler/binding.dart.js 934:9 [_invokeFrameCallback] dart_sdk.js:37972 packages/flutter/src/scheduler/binding.dart.js 893:37 handleDrawFrame dart_sdk.js:37972 packages/flutter/src/scheduler/binding.dart.js 812:12 [_handleDrawFrame] dart_sdk.js:37972 dart:sdk_internal 206710:7 invoke dart_sdk.js:37972 dart:sdk_internal 178293:15 invokeOnDrawFrame dart_sdk.js:37972 dart:sdk_internal 206481:57 <fn> dart_sdk.js:37972 dart:sdk_internal 12238:16 _checkAndCall dart_sdk.js:37972 dart:sdk_internal 12243:17 dcall dart_sdk.js:37972 dart:sdk_internal 68743:21 ret dart_sdk.js:37972 dart_sdk.js:37972 ════════════════════════════════════════════════════════════════════════════════════════════════════ 3dart_sdk.js:37972 Another exception was thrown: Converting object to an encodable object failed: Instance of '_JsonDocumentReference' dart_sdk.js:37972 Instance of 'ApiCallResponse' dart_sdk.js:37972 Another exception was thrown: Converting object to an encodable object failed: Instance of '_JsonDocumentReference'

This is the dataType AlgoliaAddress Screenshot 2024-07-18 at 19 38 44

This is the dataType ClientRecord

Screenshot 2024-07-18 at 19 39 36

This is the interceptor

import '/backend/api_requests/api_interceptor.dart';

class ExampleInterceptor extends FFApiInterceptor {
  @override
  Future<ApiCallResponse> onResponse({
    required ApiCallResponse response,
    required Future<ApiCallResponse> Function() retryFn,
  }) async {
    List<dynamic> hits = response.jsonBody['hits'];

    // Convert 'client.ref' field from string to DocumentReference
    hits = hits.map((hit) {
      if (hit['client'] != null && hit['client']['ref'] != null) {
        hit['client']['ref'] =
            FirebaseFirestore.instance.doc(hit['client']['ref']);
      } else
        hit.remove('client');
      if (hit['path'] != null) {
        hit['path'] = FirebaseFirestore.instance.doc(hit['path']);
      }
      if (hit['company'] != null) {
        hit['company'] = FirebaseFirestore.instance.doc(hit['company']);
      }
      if (hit['_geoloc'] != null) {
        hit['latlng'] = LatLng(hit['_geoloc']['lat'], hit['_geoloc']['lng']);
      }
      return hit;
    }).toList();
    final ApiCallResponse modifiedResponse =
        ApiCallResponse(hits, response.headers, response.statusCode);
    print(modifiedResponse);
    // Perform any necessary calls or modifications to the [response] prior
    // to returning it.
    return modifiedResponse;
  }
}

Expected Behavior

Api call returns response as parsed datatype normally as before

Steps to Reproduce

  1. create datatypes with document reference as a property and another property which is also a datatype containing a docRef
  2. trigger api call to retrieve these docs and parse them as the parent dataType
  3. display the response in a listview with elements of listview accessing the property

Reproducible from Blank

Bug Report Code (Required)

IT40i/LlvJd2xNtJ+KXUb8ExgmA5JkB+RoIZltVRaCotCLbkOpgcf/fOYkRoQsu+T1FMO02WhWoW0a3li/H9DvcqAzeYc74+zrVUFg2UVlOQaZSzFJWgVmhBP+VRfmbC0cG7kBFQBO5tV04jw12MAPK/XnPqQrLBO1QSDq/LZO4=

Visual documentation

Screenshot 2024-07-18 at 19 48 45

Environment

FlutterFlow v4.1.73+ released July 17, 2024
Flutter version is 3.22.2
- Platform: Web and MacOS App
- Browser name and version: Chrome
- Operating system and version affected: Mac

Additional Information

If you access my project and run test mode, please contact so I can give you credentials

Alezanello commented 1 month ago

Hello!!!

Just reading the logs i'll say the error you're encountering indicates that the object you're trying to convert to JSON contains an instance of a _JsonDocumentReference, which cannot be encoded directly. This issue arises because the FirebaseFirestore.instance.doc() method returns a DocumentReference object, which isn't directly encodable to JSON.

To resolve this, you need to convert the DocumentReference objects back to strings or some other encodable format before trying to print or use them in a JSON context.

Another exception was thrown: Converting object to an encodable object failed: Instance of '_JsonDocumentReference'

dart_sdk.js:37972 Instance of 'ApiCallResponse' dart_sdk.js:37972 Another exception was thrown: Converting object to an encodable object failed: Instance of '_JsonDocumentReference'

nicolas-gervais-42 commented 1 month ago

@Alezanello

thank you for your answer

I am parsing api response as datatype

If I do not convert to expected type in interceptor, I am getting these errors for example

String' is not a subtype of type 'DocumentReference<Object?>?

What changed in serialization / deserialization process since 3rd of July to cause this error - it was working fine before

nicolas-gervais-42 commented 1 month ago

@Alezanello

Hello,

did you have a chance to look at it ?

Best, Nicolas

Alezanello commented 1 month ago

Hey Nicolas!

Don't know if this going to work correctly but try this one:

import '/backend/api_requests/api_interceptor.dart';

class ExampleInterceptor extends FFApiInterceptor {
  @override
  Future<ApiCallResponse> onResponse({
    required ApiCallResponse response,
    required Future<ApiCallResponse> Function() retryFn,
  }) async {
    List<dynamic> hits = response.jsonBody['hits'];

    // Convert fields from string to DocumentReference
    hits = hits.map((hit) {
      if (hit['client'] != null && hit['client']['ref'] != null) {
        hit['client']['ref'] = FirebaseFirestore.instance.doc(hit['client']['ref']);
      } else {
        hit.remove('client');
      }
      if (hit['path'] != null) {
        hit['path'] = FirebaseFirestore.instance.doc(hit['path']);
      }
      if (hit['company'] != null) {
        hit['company'] = FirebaseFirestore.instance.doc(hit['company']);
      }
      if (hit['_geoloc'] != null) {
        hit['latlng'] = LatLng(hit['_geoloc']['lat'], hit['_geoloc']['lng']);
      }
      return hit;
    }).toList();

    final ApiCallResponse modifiedResponse = ApiCallResponse(
      hits,
      response.headers,
      response.statusCode,
    );

    print(modifiedResponse);

    return modifiedResponse;
  }
}


Let me know if this worked for you

nicolas-gervais-42 commented 1 month ago

@Alezanello

This is exactly the same interceptor I am already using and posted in first post...

github-actions[bot] commented 1 month 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.

Alezanello commented 1 month ago

Hello!

Sorry for the late response. Did the latest FlutterFlow updates fix your issue?

Best regards,
Azanello

nicolas-gervais-42 commented 1 month ago

Hi @Alezanello ,

No, no change unfortunately

Alezanello commented 1 month ago

Hello again,

Sorry for the late response. At this point, I'm lacking the right tools to help you with this issue. I'll keep this issue open in case I find anything that might help, but in the meantime, I recommend you contact support directly via the in-app chat or at support@flutterflow.io for a more specific solution to your situation.

Best regards,
Azanello

Alezanello commented 3 weeks ago

Closing this issue since we haven't heard back from you. If you are still facing the problem please submit a new issue. Have a great day!