pulyaevskiy / firebase-functions-interop

Firebase Functions Interop Library for Dart.
BSD 3-Clause "New" or "Revised" License
191 stars 52 forks source link

TypeError: Instance of 'JSArray': type 'JSArray' is not a subtype of type 'List<String>' #28

Closed grundid closed 5 years ago

grundid commented 6 years ago

When I post the following JSON to a cloud function I get the above error message.

{"array":["element1", "element2"]}

Example code:

void main() {
  functions['test'] = FirebaseFunctions.https.onRequest((ExpressHttpRequest request) async {
    final data = request.body;
    List<String> stringArray = data["array"];
    print(stringArray);
  });
}

This was working in an earlier Dart version. I'm using: Dart VM version: 2.0.0-dev.67.0 (Tue Jul 3 18:17:07 2018 +0200) on "macos_x64"

I guess this is more of a node_interop problem, since the dartify function is defined there. Firebase-dart uses a very similar dartify function. I'm wondering if they see a similar issue.

pulyaevskiy commented 6 years ago

Thanks for the details!

Yes, this is likely because of how dartify function works. There is no way for it to infer generic types inside lists or maps. The best it can do is return a List<dynamic> which would still fail in this case.

Not sure if this can be fixed on the node_interop side though. You might have to explicitly convert the value to desired type, e.g.:

final stringArray = new List<String>.from(data["array"]);

Or you can try and use some sort of JSON serialization library to simplify dealing with structured data. json_serializable and built_value are 2 libraries I know of, but there is probably more.

pulyaevskiy commented 5 years ago

I'm closing this issue. Since request.body can contain different types of data (lists, maps, strings) there is no way for this library to automatically convert this data to Dart types. So you should always explicitly tell what you expect, similarly to my example in above comment.