flutterpigeon

How to use `Map` type in Pigeon


How can I specify a type in Pigeon to be a Map (e.g. Map<String, String>), and preferably a Map with dynamic value types (Map<String, dynamic>. I can't know for sure what type the data values are until the push message is sent.

Attempt 1

I've tried to define a class using:

class RemoteMessage {
  Notification? notification;
  Map<String, dynamic>? data;
}

Unfortunately, I get an error message:

Error: pigeons/push.dart:6: Generic type arguments must be nullable in field "data" in class "RemoteMessage".
Error: pigeons/push.dart:6: Generic type arguments must be nullable in field "data" in class "RemoteMessage".

Attempt 2

I also tried making dynamic optional as well:

class RemoteMessage {
  Notification? notification;
  Map<String, dynamic?>? data;
}

In that case, I get only 1 instance of the error:

Error: pigeons/push.dart:6: Generic type arguments must be nullable in field "data" in class "RemoteMessage".

Attempt 3

If I make the key type optional, i.e. Map<String?, dynamic>? data;, I get the error:

Unhandled exception:
FileSystemException: Cannot open file, path = './android/app/src/main/java/dev/flutter/pigeon/Pigeon.java' (OS Error: No such file or directory, errno = 2)
#0      _File.open.<anonymous closure> (dart:io/file_impl.dart:356:9)
<asynchronous suspension>
pub finished with exit code 255

Summary

It looks like Pigeon doesn't support Map or dynamic, although it should already support generics: https://github.com/flutter/flutter/issues/63468.


Solution

  • After a couple of issues on Flutter (1 and 2), where Stuart Morgan (a developer from Google probably working on Dart / Pigeon) gave me some help, I realized that my class should look like:

    class RemoteMessage {
      Notification? notification;
      Map<String?, Object?>? data;
    }
    

    Key takeaways: