Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(push): delete FCM token and unregister iOS PN + remove streams API #47

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
45 changes: 43 additions & 2 deletions push/UPDATING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,47 @@
# Breaking changes in v2
# Updating push versions

This is a reference guide to the breaking changes introduced in v2, and how to migrate from v1.
This is a reference guide to updating your application through breaking changes in the push package.

## Breaking changes in v2.1

Similar to breaking changes in v2, listening to new tokens uses a callback based API. This removes the usage of streams completely from the API, opting for a simpler, callback API.

### Previously
```dart
final onNewTokenSubscription = Push.instance.onNewToken.listen((token) {
print("Just got a new token: $token");
});
final onNotificationTapSubscription =
Push.instance.onNotificationTap.listen((data) {
print('Notification was tapped:\n'
'Data: $data \n');
tappedNotificationPayloads.value += [data];
});
// Unsubscribe with:
onNewTokenSubscription.cancel();
onNotificationTapSubscription.cancel();
```

### Now
```dart
final unsubscribeOnNewToken = Push.instance.addOnNewToken((token) {
print("Just got a new token: $token");
});
final onNotificationTapSubscription =
Push.instance.addOnNotificationTap((data) {
print('Notification was tapped:\n'
'Data: $data \n');
tappedNotificationPayloads.value += [data];
});
// Unsubscribe with:
unsubscribeOnNewToken();
unsubscribeOnNotificationTap();
```

## Breaking changes in v2


There were breaking changes introduced in v2. See how to migrate from v1.

## Callback API

Expand Down
2 changes: 1 addition & 1 deletion push/example/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
<string>12.0</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion push/example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '11.0'
platform :ios, '12.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
12 changes: 6 additions & 6 deletions push/example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand All @@ -367,7 +367,7 @@
DEVELOPMENT_TEAM = DXY3Q8PYGP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -427,7 +427,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -477,7 +477,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand All @@ -501,7 +501,7 @@
DEVELOPMENT_TEAM = DXY3Q8PYGP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -527,7 +527,7 @@
DEVELOPMENT_TEAM = DXY3Q8PYGP;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
24 changes: 11 additions & 13 deletions push/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class MyApp extends HookWidget {

// To be informed that the device's token has been updated by the operating system
// You should update your servers with this token
final onNewTokenSubscription = Push.instance.onNewToken.listen((token) {
final unsubscribeOnNewToken = Push.instance.addOnNewToken((token) {
print("Just got a new token: $token");
});

Expand All @@ -72,8 +72,8 @@ class MyApp extends HookWidget {
});

// Handle notification taps
final onNotificationTapSubscription =
Push.instance.onNotificationTap.listen((data) {
final unsubscribeOnNotificationTap =
Push.instance.addOnNotificationTap((data) {
print('Notification was tapped:\n'
'Data: $data \n');
tappedNotificationPayloads.value += [data];
Expand Down Expand Up @@ -107,8 +107,8 @@ class MyApp extends HookWidget {
});

return () {
onNewTokenSubscription.cancel();
onNotificationTapSubscription.cancel();
unsubscribeOnNewToken();
unsubscribeOnNotificationTap();
unsubscribeOnMessage();
unsubscribeOnBackgroundMessage();
};
Expand Down Expand Up @@ -161,7 +161,7 @@ class MyApp extends HookWidget {
children: [
Text('Messages',
style: Theme.of(context).textTheme.headlineMedium),
Row(children: [
Wrap(children: [
Text('Recent foreground notification',
style: Theme.of(context).textTheme.headlineSmall),
IconButton(
Expand All @@ -171,7 +171,7 @@ class MyApp extends HookWidget {
icon: const Icon(Icons.delete))
]),
RemoteMessagesWidget(messagesReceived.value),
Row(
Wrap(
children: [
Text('Recent background notification',
style: Theme.of(context).textTheme.headlineSmall),
Expand Down Expand Up @@ -211,13 +211,10 @@ class MyApp extends HookWidget {
Text((notificationWhichLaunchedApp.value != null)
? notificationWhichLaunchedApp.value.toString()
: "The app was not launched by an app pressing the notification."),
Row(
Wrap(
children: [
Flexible(
child: Text(
'All notifications tapped since app launch',
style: Theme.of(context).textTheme.headlineSmall),
),
Text('All notifications tapped since app launch',
style: Theme.of(context).textTheme.headlineSmall),
IconButton(
onPressed: () {
tappedNotificationPayloads.value = [];
Expand Down Expand Up @@ -246,6 +243,7 @@ class MyApp extends HookWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...tappedNotificationPayloads
.map((data) => TextRow("Data", data.toString()))
Expand Down
22 changes: 21 additions & 1 deletion push/example/lib/metadata_sliver.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:push/push.dart';
import 'package:push_example/use_push_token.dart';
import 'package:share_plus/share_plus.dart';

Expand All @@ -17,6 +18,25 @@ class MetadataSliver extends HookWidget {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text('Push Token', style: Theme.of(context).textTheme.headline4),
Row(
children: [
TextButton(
child: const Text("Get token"),
onPressed: () async {
// Not necessary on Android if you subscribe to `onNewTokenSubscription`, since FCM
// will provide the token as soon as you call deleteToken.
pushToken.value = await Push.instance.token;
},
),
TextButton(
child: const Text("Delete token"),
onPressed: () async {
await Push.instance.deleteToken();
pushToken.value = "";
},
),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expand All @@ -33,7 +53,7 @@ class MetadataSliver extends HookWidget {
final position = box.localToGlobal(Offset.zero);
final rect =
Rect.fromLTWH(position.dx, position.dy, 200, 200);
Share.share("The push token is: ${pushToken.value}",
Share.share(pushToken.value ?? "Error: no token was found",
sharePositionOrigin: rect);
},
),
Expand Down
4 changes: 2 additions & 2 deletions push/example/lib/use_push_token.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:push/push.dart';

/// A custom reusable hook that gets your the push token (APNs device token or FCM registration token)
/// A custom reusable hook that gets your the push token and keeps the UI updated (APNs device token or FCM registration token)
ValueNotifier<String?> usePushToken() {
final pushToken = useState<String?>(null);
useEffect(() {
Push.instance.token.then((value) {
pushToken.value = value;
});
});
}, []);
return pushToken;
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,28 @@ class PushHostHandlers(
})
}

override fun deleteToken(callback: (Result<Unit>) -> Unit) {
FirebaseMessaging.getInstance().deleteToken().addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "Deleting FCM registration token failed", task.exception)
callback(
Result.failure(
IllegalStateException(
"Deleting FCM registration token failed",
task.exception
)
)
)
return@OnCompleteListener
};
callback(Result.success(Unit))
});
}

override fun registerForRemoteNotifications() {}

override fun unregisterForRemoteNotifications() {}

override fun backgroundFlutterApplicationReady() {
appTerminatedRemoteMessage?.let { message ->
// This signals that the manually spawned app is ready to receive a message to handle.
Expand All @@ -89,14 +111,6 @@ class PushHostHandlers(
}

private var fcmRegistrationToken: String? = null
private var isOnNewTokenListened = false
override fun onListenToOnNewToken() {
isOnNewTokenListened = true
}

override fun onCancelToOnNewToken() {
isOnNewTokenListened = false
}

override fun requestPermission(
badge: Boolean,
Expand Down Expand Up @@ -129,9 +143,7 @@ class PushHostHandlers(

fun onNewToken(fcmRegistrationToken: String) {
this.fcmRegistrationToken = fcmRegistrationToken
if (isOnNewTokenListened) {
pushFlutterApi.onNewToken(fcmRegistrationToken) { _ -> }
}
pushFlutterApi.onNewToken(fcmRegistrationToken) { _ -> }
}

fun onNotificationTap(message: RemoteMessage) {
Expand Down
Loading