Skip to content

Commit 20a9aa2

Browse files
authored
chore(llc): regular push notifications handling (#762)
* custom data docs * description added * title fix * tweaks * regular push notification handling * tweaks * tweaks * typos fix
1 parent 3789be0 commit 20a9aa2

File tree

16 files changed

+230
-40
lines changed

16 files changed

+230
-40
lines changed

docusaurus/docs/Flutter/05-advanced/02-ringing.mdx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ allows you to add an immersive calling experience to your application.
1515

1616
Ringing requires push/VoIP notifications to be sent to your device. Stream Video sends push/VoIP notifications to members that have at least one registered device.
1717

18-
Push notifications are sent in the following scenarios:
19-
- you create a call with the `ring` value set to true. In this case, a notification that shows a ringing screen is sent.
20-
- you create a call with the `notify` value set to true. In this case, a regular push notification is sent.
21-
- you haven't answered a call. In this case, a missed call notification is sent (regular push notification).
22-
2318
To receive push notifications from Stream Video, you'll need to:
2419

2520
1. Configure your push notification provider on the Stream Dashboard.

docusaurus/docs/Flutter/05-advanced/03-screen-sharing.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: screen_sharing
3-
sidebar_position: 3
3+
sidebar_position: 4
44
title: Screen Sharing
55
---
66

docusaurus/docs/Flutter/05-advanced/04-picture-in-picture.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: picture_in_picture
3-
sidebar_position: 4
3+
sidebar_position: 5
44
title: Picture in Picture (PiP)
55
---
66

docusaurus/docs/Flutter/05-advanced/05-call-recording.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
slug: /recording
3-
sidebar_position: 5
3+
sidebar_position: 6
44
title: Recording
55
---
66
A key feature of modern communication tools is the ability to quickly and easily record calls. This functionality is used for everything from quality assurance and training to legal compliance or simply as a matter of convenience for keeping track of conversations and later reviewing them.

docusaurus/docs/Flutter/05-advanced/06-screenshots.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
slug: /screenshots
3-
sidebar_position: 6
3+
sidebar_position: 7
44
title: Screenshots
55
---
66
You can take a picture of a VideoTrack at highest possible resolution. This can be useful for example if you want to take a screenshot of a screenshare at full resolution.

docusaurus/docs/Flutter/05-advanced/07-background-modes.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Background modes
33
slug: /background-modes
4-
sidebar_position: 7
4+
sidebar_position: 8
55
description: How to keep the call alive in the background
66
---
77

docusaurus/docs/Flutter/05-advanced/08-custom-data.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Custom Data
33
slug: /custom-data
4-
sidebar_position: 8
4+
sidebar_position: 9
55
description: Learn how to add and read custom data in the Stream Video Flutter SDK.
66
---
77

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
---
2+
title: Push Notifications
3+
slug: /push-notifications
4+
sidebar_position: 3
5+
description: Learn how to enable push notifications in the Stream Video Flutter SDK.
6+
---
7+
8+
Apart from the VoIP notifications for call ringing features, Stream Video Flutter SDK also supports standard push notifications. This guide will show you how to enable push notifications in your Flutter app using the Stream Video SDK.
9+
10+
Push notifications are sent in the following scenarios:
11+
- you create a call with the `ring` value set to true. In this case, a notification that shows a ringing screen is sent. (covered in the [ringing documentation](https://getstream.io/video/docs/flutter/advanced/ringing_and_callkit/))
12+
- you create a call with the `notify` value set to true. In this case, a regular push notification is sent.
13+
- you haven't answered a call. In this case, a missed call notification is sent (regular push notification).
14+
15+
## Android and Firebase Cloud Messaging (FCM)
16+
17+
For FCM the steps taken in [ringing documentation](https://getstream.io/video/docs/flutter/advanced/ringing_and_callkit/) are enough and will also handle standard push notifications.
18+
19+
In case of missed call the notification will be shown using [flutter_callkit_incoming](https://pub.dev/packages/flutter_callkit_incoming) package. It can be configured by `pushParams` when initializing `StreamVideo`:
20+
21+
```dart
22+
StreamVideo(
23+
apiKey,
24+
user: user,
25+
pushNotificationManagerProvider: StreamVideoPushNotificationManager.create(
26+
iosPushProvider: const StreamVideoPushProvider.apn(
27+
name: 'apn',
28+
),
29+
androidPushProvider: const StreamVideoPushProvider.firebase(
30+
name: 'firebase',
31+
),
32+
pushParams: const StreamVideoPushParams(
33+
appName: kAppName,
34+
ios: IOSParams(iconName: 'IconMask'),
35+
missedCallNotification: NotificationParams(
36+
showNotification: true,
37+
subtitle: 'Missed Call',
38+
callbackText: 'Call Back',
39+
)
40+
),
41+
),
42+
);
43+
```
44+
45+
If you want to handle missed call notification differently or handle the notification about incoming call (when `notify` is set to true) use the existing `_handleRemoteMessage()` method (see [ringing documentation](https://getstream.io/video/docs/flutter/advanced/ringing_and_callkit/)):
46+
47+
```dart
48+
Future<bool> _handleRemoteMessage(RemoteMessage message) async {
49+
final payload = message.data;
50+
51+
final sender = payload['sender'] as String?;
52+
final type = payload['type'] as String?;
53+
54+
if (sender == 'stream.video' && type == 'call.notification') {
55+
final callCid = payload['call_cid'] as String?;
56+
// Show notification, for example using `flutter_local_notifications` package
57+
}
58+
59+
final streamVideo = locator.get<StreamVideo>();
60+
return streamVideo.handleVoipPushNotification(
61+
message.data,
62+
handleMissedCall: false, //<-- Add this flag if you dont want a default missed call notification handling
63+
);
64+
}
65+
```
66+
67+
## iOS and Apple Push Notification Service (APNs)
68+
69+
For APNs the standard push notifications have to be handled separately of VoIP notifications. When APN push provider is registered for iOS, both VoIP and standard push notifications are send using APN by Stream Video SDK.
70+
71+
### Registering APN device token
72+
73+
First you need to register APN device token as it is separate from the VoIP token (registered out-of-the-box by the Stream Video SDK). To do this just set `registerApnDeviceToken` to true when initializing `StreamVideo` instance:
74+
75+
```dart
76+
StreamVideo(
77+
apiKey,
78+
user: user,
79+
pushNotificationManagerProvider: StreamVideoPushNotificationManager.create(
80+
iosPushProvider: const StreamVideoPushProvider.apn(
81+
name: 'flutter-apn',
82+
),
83+
androidPushProvider: const StreamVideoPushProvider.firebase(
84+
name: 'flutter-firebase',
85+
),
86+
pushParams: const StreamVideoPushParams(
87+
appName: kAppName,
88+
ios: StreamIOSParams(iconName: 'IconMask'),
89+
),
90+
registerApnDeviceToken: true, // <--- Add this line
91+
),
92+
);
93+
```
94+
95+
### Handling standard push notifications
96+
97+
Next, you need to handle the push notifications in your app.
98+
99+
To do this, you need to add the following code to your `AppDelegate.swift` file:
100+
101+
```swift
102+
@objc class AppDelegate: FlutterAppDelegate {
103+
override func application(
104+
_ application: UIApplication,
105+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
106+
) -> Bool {
107+
GeneratedPluginRegistrant.register(with: self)
108+
109+
// Register for push notifications.
110+
StreamVideoPKDelegateManager.shared.registerForPushNotifications() // <--- Add will only handle VoIP notifications
111+
UNUserNotificationCenter.current().delegate = self // <--- Add this line to handle standard push notifications
112+
113+
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
114+
}
115+
116+
// This method will be called when notification is received
117+
override func userNotificationCenter(_ center: UNUserNotificationCenter,
118+
willPresent notification: UNNotification,
119+
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
120+
let streamDict = notification.request.content.userInfo["stream"] as? [String: Any]
121+
if(streamDict?["sender"] as? String != "stream.video") {
122+
return completionHandler([])
123+
}
124+
125+
if #available(iOS 14.0, *) {
126+
completionHandler([.list, .banner, .sound])
127+
} else {
128+
completionHandler([.alert])
129+
}
130+
}
131+
}
132+
```
133+
134+
If you want to handle the notification tap event, for example to navigate to the call screen when you `notify` about it, you can add the following code to your `AppDelegate.swift` file:
135+
136+
```swift
137+
// This method will be called when notification is tapped
138+
override func userNotificationCenter(_ center: UNUserNotificationCenter,
139+
didReceive response: UNNotificationResponse,
140+
withCompletionHandler completionHandler: @escaping () -> Void) {
141+
142+
let streamDict = response.notification.request.content.userInfo["stream"] as? [String: Any]
143+
if(streamDict?["sender"] as? String != "stream.video") {
144+
return;
145+
}
146+
147+
if(streamDict?["type"] as? String == "call.notification") {
148+
let callCid = streamDict?["call_cid"] as? String
149+
print("Call notification received with call cid: \(callCid)")
150+
//Navigate to call, for example implementing method channel
151+
}
152+
153+
completionHandler()
154+
}
155+
```
156+
157+
### Push notification permission
158+
159+
Remember, that in order to receive push notifications, you need to ask the user for relevant permission. One way of doing it is using [permission_handler](https://pub.dev/packages/permission_handler) plugin.
160+
161+
```dart
162+
Permission.notification.request();
163+
```

dogfooding/ios/Podfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,16 @@ post_install do |installer|
6060
end
6161
end
6262
end
63+
64+
installer.pods_project.targets.each do |target|
65+
target.build_configurations.each do |config|
66+
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
67+
'$(inherited)',
68+
'PERMISSION_CAMERA=1',
69+
'PERMISSION_MICROPHONE=1',
70+
'PERMISSION_NOTIFICATIONS=1',
71+
]
72+
73+
end
74+
end
6375
end

dogfooding/ios/Runner/AppDelegate.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,26 @@ import stream_video_push_notification
1313

1414
// Register for push notifications.
1515
StreamVideoPKDelegateManager.shared.registerForPushNotifications()
16+
UNUserNotificationCenter.current().delegate = self
1617

1718
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
1819
}
20+
21+
// This method will be called when notification is received
22+
override func userNotificationCenter(_ center: UNUserNotificationCenter,
23+
willPresent notification: UNNotification,
24+
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
25+
let streamDict = notification.request.content.userInfo["stream"] as? [String: Any]
26+
if(streamDict?["sender"] as? String != "stream.video") {
27+
return completionHandler([])
28+
}
29+
30+
if #available(iOS 14.0, *) {
31+
completionHandler([.list, .banner, .sound])
32+
} else {
33+
completionHandler([.alert])
34+
}
35+
}
36+
37+
1938
}

0 commit comments

Comments
 (0)