Flutter AppPush Setup

Native Prerequisites

Complete the following Native AppPush Prerequisites:

• Android Key Retrieval section and Certificate Upload section.

• Android App Setup Section step 3 only.

• iOS Certificate Retrieval section and Certificate Upload section.

• iOS App Setup Section steps 1 and 2 only.

App Setup

1. Update pubspec.yaml

Add the following to pubspec.yaml file:

push:  ^2.3.0

2. Initialize Firebase and Configure Push Notifications

Add the following to main.dart file:


void main() async {

    WidgetsFlutterBinding.ensureInitialized()

    runApp(const WunderkindApp())

}


final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>()

bool _isDialogOpen = false


class WunderkindApp extends StatelessWidget {

    const WunderkindApp({Key? key}) : super(key: key)


    @override

    Widget build(BuildContext context) {

        final wunderkindSdk = Wunderkind()

        wunderkindSdk.initialize(MYSDK, false)


        return MaterialApp(

            debugShowCheckedModeBanner: false,

            title: 'DEMO APP',

            theme: ThemeData(

                primarySwatch: Colors.deepPurple,

            ),

            navigatorKey: navigatorKey,

            home: const WunderkindPage(),

        )

    }

}


Future<void> setupAppPush(BuildContext context) async {

    final isGranted = await Push.instance.requestPermission()

    if (isGranted) {

        Wunderkind.instance.trackAppPushOptIn()

    } else {

        Wunderkind.instance.trackAppPushOptOut()

    }


    Push.instance.addOnBackgroundMessage((message) {

        Map<String, dynamic>? messageData = retrieveNotificationPayload(message.data)

        if (messageData != null) {

            Wunderkind.instance.trackAppPushDelivered(messageData)

        }

    })


    var token = await Push.instance.token

    if (token != null) {

        Wunderkind.instance.trackAppPushTokenSet(token)

    }


    Push.instance.onNewToken.listen((token) {

        Wunderkind.instance.trackAppPushTokenSet(token)

    })


    Push.instance.onNotificationTap.listen((data) {

        Map<String, dynamic>? messageData = retrieveNotificationPayload(data)

        if (messageData != null) {

            Wunderkind.instance.trackAppPushDelivered(messageData)

            Wunderkind.instance.trackAppPushOpened(messageData)

        }

    })


    Push.instance.addOnMessage((message) {

        Map<String, dynamic>? messageData = retrieveNotificationPayload(message.data)

        if (messageData != null) {

            Wunderkind.instance.trackAppPushDelivered(messageData)

            showAlert(message)

        }

    })

}


Map<String, dynamic>? retrieveNotificationPayload(Map<String?, Object?>? messageData) {

    if (messageData == null) {

        return null

    }

    Map<dynamic, dynamic>? data = messageData as Map<dynamic, dynamic>?

    if (data != null) {

        Map<String, dynamic> dataMap = convertMapToStringDynamic(data)

        return dataMap

    }

    return null

}


void showAlert(dynamic data) {

    if (_isDialogOpen) {

        return

    }

    String? title

    String? body


    if (data is RemoteMessage) {

        title = data.notification?.title

        body = data.notification?.body

    } else if (data is Map<dynamic, dynamic>) {

        Map<dynamic, dynamic>? aps = data['aps'] as Map<dynamic, dynamic>?

        Map<dynamic, dynamic>? alert = aps?["alert"] as Map<dynamic, dynamic>?

        title = alert?['title'] as String

        body = alert?['body'] as String

    }


    _isDialogOpen = true

    showDialog(

        context: navigatorKey.currentContext!,

        builder: (BuildContext context) {

            return AlertDialog(

                title: Text(title ?? 'Notification'),

                content: Text(body ?? 'You have received a new notification.'),

                actions: [

                    TextButton(

                        child: const Text("Ignore"),

                        onPressed: () {

                            _isDialogOpen = false

                            Navigator.of(context).pop()

                        },

                    ),

                    TextButton(

                        child: const Text("Let's go!"),

                        onPressed: () {

                            _isDialogOpen = false

                            Navigator.of(context).pop()

                        },

                    )

                ],

            )

        },

    ).then((_) => _isDialogOpen = false)

}