Skip to main content

Push Notifications

The MeetingDoctors SDK uses Firebase Cloud Messaging (FCM) to deliver push notifications related to SDK events.

These notifications may include:

  • Chat messages
  • Video call ready notifications (sent when the professional joins the video consultation)
  • Appointment reminders

Push notifications allow the application to notify the user even when the app is in background or closed.
The SDK processes these notifications internally once they are forwarded by the host application.


Prerequisites

info

Firebase must be configured in the iOS application. See the official Firebase documentation:
https://firebase.google.com/docs/cloud-messaging/ios/client

To enable MeetingDoctors push notifications, there are two options:

  1. Use an existing Firebase project
    Provide the following values from the Firebase console:

    • Sender ID
    • Firebase Service Account
  2. Firebase project provided by MeetingDoctors
    Provide:

    • iOS: .p8 key file, Team ID, and Key ID

Required Permissions and Capabilities

The host application must have the required entitlements and capabilities enabled to receive push notifications.

  • Push Notifications entitlement must be enabled

  • Background Modes should include fetch and remote-notification (recommended)

<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>

Step-by-Step Integration

Step 1 — Authenticate the User

Push notifications must be registered after a successful SDK authentication.

try await MeetingDoctors.authenticate()

Step 2 — Retrieve the Firebase Token

Firebase generates a device registration token (FCM token). This token uniquely identifies the device for push delivery.

The token can be retrieved using the Firebase Messaging SDK:

Messaging.messaging().token { token, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
} else if let token = token {
print("FCM registration token: \(token)")
}
}
info

The Firebase token can change over time. Whenever Firebase generates a new token, it must be registered again in the SDK.

Step 3 — Register the Token in the SDK

Once the token is obtained, it must be registered in the MeetingDoctors SDK:

try await MeetingDoctors.registerFirebaseForNotifications(token: token)

Step 4 — Enable Notification Delivery

Once the token is registered, the MeetingDoctors backend can send push notifications through Firebase Cloud Messaging when relevant events occur.


Runtime Handling

After setup, incoming pushes must be forwarded to the SDK so the payload can be processed and the corresponding internal event can be triggered.

The entry point depends on the application state.

App in Foreground

When the app is running in the foreground and a notification is delivered, iOS calls:

  • userNotificationCenter(_:willPresent:withCompletionHandler:)

Forward the notification to the SDK:

func userNotificationCenter(
_ userNotificationCenter: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
MeetingDoctors.userNotificationCenter(userNotificationCenter, willPresent: notification) { result in
switch result {
case let .success(options):
completionHandler(options)
case .failure:
completionHandler([.alert, .badge, .sound])
}
}
}

This allows the SDK to decide how the notification should be presented while the app is active.

App in Background

When the app is in background and the user taps the notification, iOS calls:

  • userNotificationCenter(_:didReceive:withCompletionHandler:)

Forward the response to the SDK:

func userNotificationCenter(
_ userNotificationCenter: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
MeetingDoctors.userNotificationCenter(userNotificationCenter, didReceive: response) { result in
switch result {
case .success:
completionHandler()
case .failure:
completionHandler()
}
}
}

This is the standard entry point for handling notification interaction.

In some cases it may be recommended to inspect the notification payload to determine whether it belongs to MeetingDoctors and route the user accordingly.

This can be done by resolving the notification payload into a MeetingDoctorsDeeplinkOption:

let userInfo = response.notification.request.content.userInfo
let deeplink = MeetingDoctors.deeplinkOption(for: userInfo)

if deeplink != .unknown {
// Example: route to the corresponding screen depending on the deeplink option
}

This approach can be useful when the application needs to navigate directly to a specific screen such as a videocall, messenger, appointment, or consultation.

App Closed (Cold Start)

When the app is not running and the user opens it by tapping the notification, the notification payload is delivered through launchOptions in:

  • application(_:didFinishLaunchingWithOptions:)

A generic implementation pattern is:

  1. Extract the push userInfo from launchOptions.

Forward it to the SDK for processing (method depends on the notification type and SDK integration).

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {

if let remoteNotification = launchOptions?[.remoteNotification] as? [AnyHashable: Any] {
let deeplink = MeetingDoctors.deeplinkOption(for: userInfo)

if deeplink != .unknown {
// Example: route to the corresponding screen depending on the deeplink option
}
}

return true
}

Handling cold start pushes ensures that taps on notifications behave consistently even when the app was previously terminated.


Example Push Notification Payload

A push notification payload received by the application may contain several fields depending on the event type.

A simplified example is shown below:

{
"type": "event_type",
"module": "module_name",
"message": {
"title": "Notification title",
"body": "Notification message"
},
"...": "other fields depending on the event"
}

Only a subset of fields is shown here. The payload may include additional information depending on the type of event (chat message, video call, appointment reminder, etc.).

For iOS devices, the payload also includes the standard APNs aps block, which defines the content displayed by the system notification.

Example:

{
"aps": {
"alert": {
"title": "Notification title",
"body": "Notification message"
},
"badge": 1,
"sound": "default",
"content-available": 1,
"mutable-content": 1
}
}

When the notification is received by the application, this payload is available through the userInfo dictionary of the notification.

let userInfo = response.notification.request.content.userInfo

This payload can then be forwarded to the SDK for processing.


Get Pending Messages Count

Once authentication is completed, retrieve the unread message count:

let filter = MeetingDoctorsFilter.default
let unreadCount = try await MeetingDoctors.unreadMessageCount(with: filter)

The returned value represents the total number of messages pending to be read.