diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart b/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart index c9e607d74929..a128fbf5f55c 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/firebase_messaging_web.dart @@ -4,7 +4,7 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:html'; +import 'dart:js_interop'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core_web/firebase_core_web.dart'; @@ -12,6 +12,7 @@ import 'package:firebase_core_web/firebase_core_web_interop.dart' as core_interop; import 'package:firebase_messaging_platform_interface/firebase_messaging_platform_interface.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:web/web.dart' as web; import 'src/internals.dart'; import 'src/interop/messaging.dart' as messaging_interop; @@ -129,7 +130,7 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform { @override Future getNotificationSettings() async { - return utils.getNotificationSettings(Notification.permission); + return utils.getNotificationSettings(web.Notification.permission); } @override @@ -143,7 +144,8 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform { bool sound = true, }) { return convertWebExceptions(() async { - String status = await Notification.requestPermission(); + String status = + (await web.Notification.requestPermission().toDart)! as String; return utils.getNotificationSettings(status); }); } diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart index e3ab570ba356..5bdbe670d070 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging.dart @@ -6,6 +6,7 @@ // ignore_for_file: public_member_api_docs import 'dart:async'; +import 'dart:js_interop'; import 'package:firebase_core_web/firebase_core_web_interop.dart'; import 'package:js/js.dart'; @@ -32,25 +33,26 @@ class Messaging extends JsObjectWrapper { } static Future isSupported() => - handleThenable(messaging_interop.isSupported()); + messaging_interop.isSupported().toDart.then((value) => value! as bool); Messaging._fromJsObject(messaging_interop.MessagingJsImpl jsObject) : super.fromJsObject(jsObject); /// To forcibly stop a registration token from being used, delete it by calling this method. /// Calling this method will stop the periodic data transmission to the FCM backend. - Future deleteToken() => - handleThenable(messaging_interop.deleteToken(jsObject)); + Future deleteToken() => messaging_interop.deleteToken(jsObject).toDart; /// After calling [requestPermission] you can call this method to get an FCM registration token /// that can be used to send push messages to this user. Future getToken({String? vapidKey}) async { try { - final token = await handleThenable(messaging_interop.getToken( - jsObject, - vapidKey == null - ? null - : messaging_interop.GetTokenOptions(vapidKey: vapidKey))); + final token = (await messaging_interop + .getToken( + jsObject, + vapidKey == null + ? null + : messaging_interop.GetTokenOptions(vapidKey: vapidKey.toJS)) + .toDart)! as String; return token; } catch (err) { // A race condition can happen in which the service worker get registered @@ -78,15 +80,18 @@ class Messaging extends JsObjectWrapper { StreamController? _controller = controller; if (_controller == null) { _controller = StreamController.broadcast(sync: true); - final nextWrapper = allowInterop((payload) { - _controller!.add(MessagePayload._fromJsObject(payload)); + final nextWrapper = allowInterop((JSAny payload) { + _controller!.add(MessagePayload._fromJsObject( + payload as messaging_interop.MessagePayloadJsImpl)); }); - final errorWrapper = allowInterop((e) { + final errorWrapper = allowInterop((JSError e) { _controller!.addError(e); }); - messaging_interop.onMessage(jsObject, - messaging_interop.Observer(next: nextWrapper, error: errorWrapper)); + messaging_interop.onMessage( + jsObject, + messaging_interop.Observer( + next: nextWrapper.toJS, error: errorWrapper.toJS)); } return _controller.stream; } @@ -98,9 +103,9 @@ class NotificationPayload messaging_interop.NotificationPayloadJsImpl jsObject) : super.fromJsObject(jsObject); - String? get title => jsObject.title; - String? get body => jsObject.body; - String? get image => jsObject.image; + String? get title => jsObject.title?.toDart; + String? get body => jsObject.body?.toDart; + String? get image => jsObject.image?.toDart; } class MessagePayload @@ -108,8 +113,8 @@ class MessagePayload MessagePayload._fromJsObject(messaging_interop.MessagePayloadJsImpl jsObject) : super.fromJsObject(jsObject); - String get messageId => jsObject.messageId; - String? get collapseKey => jsObject.collapseKey; + String get messageId => jsObject.messageId.toDart; + String? get collapseKey => jsObject.collapseKey?.toDart; FcmOptions? get fcmOptions => jsObject.fcmOptions == null ? null : FcmOptions._fromJsObject(jsObject.fcmOptions!); @@ -117,13 +122,13 @@ class MessagePayload ? null : NotificationPayload._fromJsObject(jsObject.notification!); Map? get data => dartify(jsObject.data); - String? get from => jsObject.from; + String? get from => jsObject.from?.toDart; } class FcmOptions extends JsObjectWrapper { FcmOptions._fromJsObject(messaging_interop.FcmOptionsJsImpl jsObject) : super.fromJsObject(jsObject); - String? get analyticsLabel => jsObject.analyticsLabel; - String? get link => jsObject.link; + String? get analyticsLabel => jsObject.analyticsLabel?.toDart; + String? get link => jsObject.link?.toDart; } diff --git a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart index f12160b7fe8d..344afa6e626c 100644 --- a/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart +++ b/packages/firebase_messaging/firebase_messaging_web/lib/src/interop/messaging_interop.dart @@ -8,73 +8,97 @@ @JS('firebase_messaging') library firebase_interop.messaging; +import 'dart:js_interop'; + import 'package:firebase_core_web/firebase_core_web_interop.dart'; -import 'package:js/js.dart'; @JS() +@staticInterop external MessagingJsImpl getMessaging([AppJsImpl? app]); @JS() -external PromiseJsImpl deleteToken(MessagingJsImpl messaging); +@staticInterop +external JSPromise /* bool */ deleteToken(MessagingJsImpl messaging); @JS() -external PromiseJsImpl getToken( +@staticInterop +external JSPromise /* String */ getToken( MessagingJsImpl messaging, GetTokenOptions? getTokenOptions); @JS('isSupported') -external PromiseJsImpl isSupported(); +@staticInterop +external JSPromise /* bool */ isSupported(); @JS() -external void Function() onMessage( +@staticInterop +external JSFunction onMessage( MessagingJsImpl messaging, Observer observer, ); @JS('Messaging') +@staticInterop abstract class MessagingJsImpl {} @JS() +@staticInterop @anonymous class Observer { - external dynamic get next; - external dynamic get error; - external factory Observer({dynamic next, dynamic error}); + external factory Observer({JSAny next, JSAny error}); +} + +extension ObserverJsImplX on Observer { + external JSAny get next; + external JSAny get error; } @JS() +@staticInterop @anonymous class GetTokenOptions { - external String get vapidKey; // TODO - I imagine we won't be implementing serviceWorkerRegistration type as it extends EventTarget class // external String get serviceWorkerRegistration external factory GetTokenOptions({ - String? vapidKey, + JSString? vapidKey, /*dynamic serviceWorkerRegistration */ }); } +extension GetTokenOptionsJsImplX on GetTokenOptions { + external JSString get vapidKey; +} + @JS() +@staticInterop @anonymous -abstract class NotificationPayloadJsImpl { - external String? get title; - external String? get body; - external String? get image; +abstract class NotificationPayloadJsImpl {} + +extension NotificationPayloadJsImplX on NotificationPayloadJsImpl { + external JSString? get title; + external JSString? get body; + external JSString? get image; } @JS() +@staticInterop @anonymous -abstract class MessagePayloadJsImpl { - external String get messageId; - external String? get collapseKey; +abstract class MessagePayloadJsImpl {} + +extension MessagePayloadJsImplX on MessagePayloadJsImpl { + external JSString get messageId; + external JSString? get collapseKey; external FcmOptionsJsImpl? get fcmOptions; external NotificationPayloadJsImpl? get notification; - external dynamic /*Map*/ get data; - external String? get from; + external JSObject get data; + external JSString? get from; } @JS() +@staticInterop @anonymous -abstract class FcmOptionsJsImpl { - external String? get analyticsLabel; - external String? get link; +abstract class FcmOptionsJsImpl {} + +extension FcmOptionsJsImplX on FcmOptionsJsImpl { + external JSString? get analyticsLabel; + external JSString? get link; } diff --git a/packages/firebase_messaging/firebase_messaging_web/pubspec.yaml b/packages/firebase_messaging/firebase_messaging_web/pubspec.yaml index a3b04394fee7..1da25cbf11e6 100644 --- a/packages/firebase_messaging/firebase_messaging_web/pubspec.yaml +++ b/packages/firebase_messaging/firebase_messaging_web/pubspec.yaml @@ -5,7 +5,7 @@ repository: https://github.com/firebase/flutterfire/tree/master/packages/firebas version: 3.5.18 environment: - sdk: '>=2.18.0 <4.0.0' + sdk: '>=3.2.0 <4.0.0' flutter: '>=3.3.0' dependencies: @@ -19,6 +19,7 @@ dependencies: sdk: flutter js: ^0.6.3 meta: ^1.8.0 + web: '>=0.3.0 <0.5.0' dev_dependencies: firebase_core_platform_interface: ^5.0.0