Flutter

Flutter changes nothing on the Push side. The Dart code below fetches the same platform token a native app would and registers it with one request. It will not deliver anything until the app in the console has both keys: the Firebase key for Android and the APNs key for iPhones.

The SDK

Flutter 1.6.0 passes its tests, and bolrach_push goes up on pub.dev once the publishing account exists.

Meanwhile this page uses firebase_messaging from pub.dev.

Register and report

// flutter pub add firebase_core firebase_messaging
import 'dart:io' show Platform;
import 'package:firebase_messaging/firebase_messaging.dart';

Future<void> enablePush(PushApi push) async {
  final settings = await FirebaseMessaging.instance.requestPermission();
  if (settings.authorizationStatus == AuthorizationStatus.denied) return;

  final isIOS = Platform.isIOS;
  final token = isIOS
      ? await FirebaseMessaging.instance.getAPNSToken()   // the raw APNs token: we talk to Apple directly
      : await FirebaseMessaging.instance.getToken();       // an FCM token
  if (token == null) return;
  await push.register(token: token, platform: isIOS ? 'ios' : 'android', provider: isIOS ? 'apns' : 'fcm');

  FirebaseMessaging.instance.onTokenRefresh.listen((fresh) =>
      push.register(token: fresh, platform: 'android', provider: 'fcm'));

  FirebaseMessaging.onMessageOpenedApp.listen((message) =>
      push.report(deliveryId: message.data['delivery_id'], event: 'opened'));
}

push.register makes the POST /installations call from the Android page. push.report sends receipts to /receipts, signed with the receipt token that registration returned.

Machine-readable: openapi.json. Console: bolrach.com/push.