Skip to content

message_codes should explicitly support Map<String, dynamic> to better support JSON (Firebase) #17417

Description

@jmrboosties

@kevmoo suggested i file an issue report here in regards to our discussion in this thread: google/json_serializable.dart#137

To summarize, Flutter's Firebase package returns documents from Firestore collections as _InternalLinkedHashMap<dynamic, dynamic>, but Flutter's recommended json package json_serializable expects json to come in as a Map<String, dynamic>. This results in the following error:

I/flutter ( 6352): type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' where
I/flutter ( 6352):   _InternalLinkedHashMap is from dart:collection
I/flutter ( 6352):   Map is from dart:core
I/flutter ( 6352):   String is from dart:core

Here is an example of some code which will trigger this:

_firestore = Firestore.instance;

return _firestore.collection('favorites').where('user_id', isEqualTo: uid).getDocuments()
				.then((querySnap) {
					querySnap.documents.forEach((document) {
						print(document.data);

						Map<String, dynamic> json = document.data; //casts, but if you put breaklines through this its that _InternalLinkedHashMap<dynamic, dynamic> type
						Album album = new Album.fromJson(json['favorite_albums'][0]); //Throws the type exception
					});
				})
				.catchError((error) {
					print(error);
				});

Thank you!

Activity

  1. sbesnard commented on May 31, 2018

    @sbesnard

    It is a bug, in the meantime, you can use something like this

    If you have nested Map, well, you will have to manually modify the .g.dart file to replace casts by Map<String, dynamic>.from()

  2. kevmoo commented on May 31, 2018

    @kevmoo
    Contributor
  3. sbesnard commented on May 31, 2018

    @sbesnard

    Wow, took me ages to find how to use this... I had to create a build.yaml.
    Any other way ? the documentation is not clear on how to use this flag with the command line.
    Thanks

  4. kevmoo commented on May 31, 2018

    @kevmoo
    Contributor

    build.yaml with this content should be good. Did you try that?

    targets:
      $default:
        builders:
          json_serializable:
            options:
              any_map: true
  5. sbesnard commented on May 31, 2018

    @sbesnard

    I did, and it worked, my question was : how to pass the anyMap parameter without using a build.yaml (ie in the command line)

  6. jakemac53 commented on May 31, 2018

    @jakemac53
    Contributor

    We do support a --define flag which is a bit verbose but would look something like this:

    --define "json_serializable=any_map=true"
    
  7. added this to the milestone on Jun 12, 2018
  8. escamoteur commented on Jun 18, 2018

    @escamoteur
    Contributor

    jaguar_serializer is also affected by this issue @tejainece

  9. escamoteur commented on Jun 19, 2018

    @escamoteur
    Contributor

    For jaguar_serializer this was fixed right now

    jaguar_serializer: 2.1.5
    jaguar_serializer_cli. 2.1.14
  10. paprikanotfound commented on Jul 28, 2018

    @paprikanotfound

    Setting any_map to true didn't work for me. Any tips?
    Currently using a workaround found here: #15007

  11. escamoteur commented on Jul 28, 2018

    @escamoteur
    Contributor

    As said better use jaguar_serializer with Firebase

  12. kevmoo commented on Jul 28, 2018

    @kevmoo
    Contributor

    @stavangr – are you getting the same errors? Have you upgraded the flutter plugin to latest?

  13. 26 remaining items

  14. marcelino-borges commented on Aug 1, 2019

    @marcelino-borges

    Hey guys!
    I've struggling so much these days trying to get this json stuff working.
    The sad part of it is that I remember using Firebase with native android framework (java) and things used to be so simple and easy, no need of json... And with Flutter we have to struggle like this to parse to/from json all the time, and there is always a problem showing up. =(

    Just to let you know... the build.yaml has worked for me.

    And do not forget to execute the flutter pub run build_runner build in the terminal before trying again!

    My exception:
    Unhandled Exception: type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' in type cast

    flutter doctor:
    `Doctor summary (to see all details, run flutter doctor -v):
    [√] Flutter (Channel stable, v1.7.8+hotfix.4, on Microsoft Windows [versão 10.0.17763.615], locale pt-BR)

    [√] Android toolchain - develop for Android devices (Android SDK version 29.0.0)
    [√] Android Studio (version 3.3)
    [!] IntelliJ IDEA Community Edition (version 2019.1)
    X Flutter plugin not installed; this adds Flutter specific functionality.
    [!] VS Code (version 1.35.0)
    X Flutter extension not installed; install from
    https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
    [√] Connected device (1 available)

    ! Doctor found issues in 2 categories.
    `

  15. ChristBKK commented on Aug 4, 2019

    @ChristBKK

    got this problem now also. Is there any fix?

  16. tapizquent commented on Aug 29, 2019

    @tapizquent

    Got this same exception just now coming from code generated by JsonSerializable

    Unhandled Exception: type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' in type cast

    Currently using:

    • iOS Simulator
    • Flutter 1.9.5 channel dev
    • JsonSerializable v 3.2.2

    I have identified that it is because of inner Maps. Root map converts just fine.

    Has any solutions come up yet?

    UPDATE

    Adding parameter anyMap:true to all JsonSerializable constructors that included inner maps and works fine. As mentioned above, this seems to be a workaround and not a fixed, so will continue waiting for a fix.

  17. fiskurgit commented on Sep 2, 2019

    @fiskurgit

    This is frustrating, like a lot of developers my test project with Flutter is porting an established Android/iOS app that uses Firebase, at this point I hit a brick wall when trying to serialise some simple Json:

    var remoteConfig = await config.fetchRemoteConfig();
    var configUrls = remoteConfig.getString("configUrls");
    print("Config urls: " + configUrls);
    var configUrlsJson = json.decode(configUrls);
    

    [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'

  18. marcelino-borges commented on Sep 3, 2019

    @marcelino-borges

    Guys, please check again flutter oficial docs about json serializable (https://flutter.dev/docs/development/data-and-backend/json). I've made a pull request recently and it was already merged.

    Look for the nested classes section, there are a few tricks worth to be tried. There is the "anyMap: true" trick and a bit more. Check it out and see if it works for you.

  19. fiskurgit commented on Sep 3, 2019

    @fiskurgit

    As a new Flutter dev the path for lots of people is the above, everything is smooth then they hit this issue when they try and work with Json - workarounds aren't the point. After being stuck for a few of hours, going away and coming back to it again I found: Map<String, dynamic> configUrlsJson = jsonDecode(configUrlsString); - seems obvious now, but not to a noob in Flutter/Dart.

    It might not seem a big issue for seasoned Dart devs but orientating in a new language and framework takes time, anyMap: true sounds so simple, but then they have to find out where to put that, build.yaml right? Cool, so where does that live? More research, then you have to run another command to rebuild with flutter pub run build_runner build - all of this for a new Dart/Flutter developer is bewildering. The issue is I believe over a year old, and it's tripping a lot of people up: json.decode should just work.

  20. kroikie commented on Oct 13, 2019

    @kroikie

    @jmrboosties

    This issue has been moved to firebase/flutterfire#833. Any further collaboration will be done there.

  21. tewshi commented on Dec 9, 2019

    @tewshi

    Wow, took me ages to find how to use this... I had to create a build.yaml.
    Any other way ? the documentation is not clear on how to use this flag with the command line.
    Thanks

    after doing this, don't forget to
    flutter pub run build_runner build --delete-conflicting-outputs

  22. github-actions commented on Aug 15, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  23. locked as resolved and limited conversation to collaborators on Aug 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: crashStack traces logged to the consolep: cloud_firestoreObsolete - Firebase Firestore pluginp: firebaseObsolete - Firebase pluginsp: firebase_databaseObsolete - The Firebase Database pluginpackageflutter/packages repository. See also p: labels.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions