Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,17 @@ class FirebaseMessaging extends FirebasePluginPlatform {
/// Returns the default FCM token for this device.
///
/// On web, a [vapidKey] is required.
///
/// On web, a custom messaging service worker can be registered with
/// [serviceWorkerScriptPath]. This must point to a JavaScript file in the
/// root of the app's `web` directory.
Future<String?> getToken({
String? vapidKey,
String? serviceWorkerScriptPath,
}) {
return _delegate.getToken(
vapidKey: vapidKey,
serviceWorkerScriptPath: serviceWorkerScriptPath,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,35 @@ void main() {
group('getToken', () {
test('verify delegate method is called with correct args', () async {
const vapidKey = 'test-vapid-key';
when(kMockMessagingPlatform.getToken(vapidKey: anyNamed('vapidKey')))
.thenAnswer((_) => Future.value(''));
when(kMockMessagingPlatform.getToken(
vapidKey: anyNamed('vapidKey'),
serviceWorkerScriptPath: anyNamed('serviceWorkerScriptPath'),
)).thenAnswer((_) => Future.value(''));

await messaging!.getToken(vapidKey: vapidKey);

verify(kMockMessagingPlatform.getToken(vapidKey: vapidKey));
verify(kMockMessagingPlatform.getToken(
vapidKey: vapidKey,
serviceWorkerScriptPath: null,
));
});

test('verify delegate method is called with service worker path',
() async {
const serviceWorkerScriptPath = 'custom-messaging-sw.js';
when(kMockMessagingPlatform.getToken(
vapidKey: anyNamed('vapidKey'),
serviceWorkerScriptPath: anyNamed('serviceWorkerScriptPath'),
)).thenAnswer((_) => Future.value(''));

await messaging!.getToken(
serviceWorkerScriptPath: serviceWorkerScriptPath,
);

verify(kMockMessagingPlatform.getToken(
vapidKey: null,
serviceWorkerScriptPath: serviceWorkerScriptPath,
));
});
});

Expand Down
7 changes: 5 additions & 2 deletions packages/firebase_messaging/firebase_messaging/test/mock.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@ class MockFirebaseMessaging extends Mock
}

@override
Future<String> getToken({String? vapidKey}) {
Future<String> getToken({String? vapidKey, String? serviceWorkerScriptPath}) {
return super.noSuchMethod(
Invocation.method(#getToken, [], {#vapidKey: vapidKey}),
Invocation.method(#getToken, [], {
#vapidKey: vapidKey,
#serviceWorkerScriptPath: serviceWorkerScriptPath
}),
returnValue: Future<String>.value(''),
returnValueForMissingStub: Future<String>.value(''));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform {
@override
Future<String?> getToken({
String? vapidKey, // not used yet; web only property
String? serviceWorkerScriptPath, // web only property
}) async {
await _APNSTokenCheck();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ abstract class FirebaseMessagingPlatform extends PlatformInterface {
/// Returns the default FCM token for this device and optionally [senderId].
Future<String?> getToken({
String? vapidKey,
String? serviceWorkerScriptPath,
}) {
throw UnimplementedError('getToken() is not implemented');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform {
}

@override
Future<String?> getToken({String? vapidKey}) async {
Future<String?> getToken(
{String? vapidKey, String? serviceWorkerScriptPath}) async {
_delegate;

if (!_initialized) {
Expand All @@ -121,7 +122,8 @@ class FirebaseMessagingWeb extends FirebaseMessagingPlatform {
}

return convertWebExceptions(
() => _delegate.getToken(vapidKey: vapidKey),
() => _delegate.getToken(
vapidKey: vapidKey, serviceWorkerScriptPath: serviceWorkerScriptPath),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'dart:async';
import 'dart:js_interop';

import 'package:firebase_core_web/firebase_core_web_interop.dart';

import 'package:web/web.dart' as web;
import 'messaging_interop.dart' as messaging_interop;

export 'messaging_interop.dart';
Expand Down Expand Up @@ -43,15 +43,24 @@ class Messaging extends JsObjectWrapper<messaging_interop.MessagingJsImpl> {

/// 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<String> getToken({String? vapidKey}) async {
Future<String> getToken(
{String? vapidKey, String? serviceWorkerScriptPath}) async {
try {
web.ServiceWorkerRegistration? serviceWorkerRegistration;
if (serviceWorkerScriptPath != null) {
serviceWorkerRegistration = await web.window.navigator.serviceWorker
.register(serviceWorkerScriptPath.toJS)
.toDart;
}
final token = (await messaging_interop
.getToken(
jsObject,
vapidKey == null
vapidKey == null && serviceWorkerRegistration == null
? null
: messaging_interop.GetTokenOptions(
vapidKey: vapidKey.toJS))
vapidKey: vapidKey?.toJS,
serviceWorkerRegistration: serviceWorkerRegistration,
))
.toDart)
.toDart;
return token;
Expand All @@ -62,7 +71,10 @@ class Messaging extends JsObjectWrapper<messaging_interop.MessagingJsImpl> {
if (err.toString().toLowerCase().contains('no active service worker') &&
firstGetTokenCall) {
firstGetTokenCall = false;
return getToken(vapidKey: vapidKey);
return getToken(
vapidKey: vapidKey,
serviceWorkerScriptPath: serviceWorkerScriptPath,
);
}
rethrow;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
library;

import 'dart:js_interop';
import 'package:web/web.dart' as web;

import 'package:firebase_core_web/firebase_core_web_interop.dart';

Expand Down Expand Up @@ -50,8 +51,10 @@ extension type GetTokenOptions._(JSObject _) implements JSObject {
external factory GetTokenOptions({
JSString? vapidKey,
/*dynamic serviceWorkerRegistration */
web.ServiceWorkerRegistration? serviceWorkerRegistration,
});
external JSString get vapidKey;
external web.ServiceWorkerRegistration get serviceWorkerRegistration;
}

extension type NotificationPayloadJsImpl._(JSObject _) implements JSObject {
Expand Down
Loading