|
- /*
- ==============================================================================
-
- This file is part of the JUCE 7 technical preview.
- Copyright (c) 2022 - Raw Material Software Limited
-
- You may use this code under the terms of the GPL v3
- (see www.gnu.org/licenses).
-
- For the technical preview this file cannot be licensed commercially.
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- #pragma once
-
- namespace juce
- {
-
- /** Singleton class responsible for push notifications functionality. Both remote and
- local notifications are supported. To get information about notifications,
- register a listener on your application startup. It is best to register the
- listener as soon as possible, because your application can be launched from
- a push notification too.
-
- To send a local notification create an instance of Notification, fill the necessary
- fields and call PushNotifications::sendLocalNotification(). When receiving local or
- remote notifications, inspect the Notification's fields for notification details.
- Bear in mind that some fields will not be available when receiving a remote
- notification.
-
- @tags{GUI}
- */
- class JUCE_API PushNotifications : private DeletedAtShutdown
- {
- public:
- #ifndef DOXYGEN
- JUCE_DECLARE_SINGLETON (PushNotifications, false)
- #endif
-
- //==============================================================================
- /** Represents a notification that can be sent or received. */
- struct Notification
- {
- Notification() = default;
- Notification (const Notification& other);
-
- /** Checks whether a given notification is correctly configured for a given OS. */
- bool isValid() const noexcept;
-
- /** Represents an action on a notification that can be presented as a button or a text input.
- On Android, each notification has its action specified explicitly, on iOS you configure an
- allowed set of actions on startup and pack them into categories (see Settings).
- */
- struct Action
- {
- /** Controls the appearance of this action. */
- enum Style
- {
- button, /**< Show this action as a button. */
- text /**< Show this action as a text input field (on Android API 20 or higher is required). */
- };
-
- /** @name Common fields */
- /**@{*/
- Style style = button;
- String title; /**< Required. the name of the action displayed to the user. */
- String textInputPlaceholder; /**< Optional: placeholder text for text input notification.
- Note that it will be ignored if button style is used. */
- var parameters; /**< Optional: additional parameters that can be passed. */
- /**@}*/
-
- /** @name iOS only fields */
- /**@{*/
- String identifier; /**< Required: unique identifier. This should be one of the
- identifiers set with requestPermissionsWithSettings(). */
- bool triggerInBackground = false; /**< Whether the app can process the action in background. */
- bool destructive = false; /**< Whether to display the action as destructive. */
- String textInputButtonText; /**< Optional: Text displayed on text input notification
- button (from iOS 10 only).
- Note that it will be ignored if style is set to Style::button. */
- /**@}*/
-
- /** @name Android only fields */
- /**@{*/
- String icon; /**< Optional: name of an icon file (without an extension) to be used for
- this action. This must be the name of one of the image
- files included into resources when exporting an Android project
- (see "Extra Android Raw Resources" setting in Projucer).
- Note that not all Android versions support an icon for an action, though
- it is recommended to provide it nevertheless. */
-
- StringArray allowedResponses; /**< Optional: a list of possible answers if the answer set is limited.
- When left empty, then the user will be able to input any text. */
- /**@}*/
- };
-
- //==============================================================================
- /** @name Common fields */
- /**@{*/
-
- String identifier; /**< Required: unique id that can be used to later dismiss the notification
- (on iOS available from version 10). */
-
- String title; /**< Required: the title of the notification, usually displayed in the first row. */
- String body; /**< Required: the content of the notification, usually displayed in the second row. */
- String subtitle; /**< Optional: additional text, that may be displayed e.g. in the third row or in the header
- area. Note that on Android, depending on OS version, this may fight for
- space with other components of the notification, so use this field
- judiciously. On iOS available from version 10. On Android available from API 16. */
-
- String groupId; /**< Optional: allows the OS to visually group, collapse, and expand a set of notifications,
- note that OS may automatically group notifications if no groupId is specified.
- Available on Android API 20 or above and iOS 10 or above. */
-
- int badgeNumber = 0; /**< Optional: on platforms that support it, can set a number this notification represents. */
- URL soundToPlay; /**< Optional: empty when the notification should be silent. When the name is set to
- "default_os_sound", then a default sound will be used.
-
- For a custom sound on OSX, set the URL to the name of a sound file (preferably without
- an extension) and place the sound file directly in bundle's "Resources" directory (you
- can use "Xcode Resource" tickbox in Projucer to achieve that), i.e. it cannot be in a
- subdirectory of "Resources" like "Resources/sound". Alternatively, if a sound file
- cannot be found in bundle's "Resources" directory, the OS may look for the sound in the
- following paths: "~/Library/Sounds", "/Library/Sounds", "/Network/Library/Sounds",
- "/System/Library/Sounds".
-
- For a custom sound on iOS, set the URL to a relative path within your bundle, including
- file extension. For instance, if your bundle contains "sounds" folder with "my_sound.caf"
- file, then the URL should be "sounds/my_sound.caf".
-
- For a custom sound on Android, set URL to the name of a raw resource file
- (without an extension) that was included when exporting an Android project in
- Projucer (see "Extra Android Raw Resources" setting). */
-
- var properties; /**< Optional: collection of additional properties that may be passed as a dictionary. */
-
- /**@}*/
-
- //==============================================================================
- /** @name iOS only fields */
- /**@{*/
-
- String category; /**< Required: determines set of actions that will appear (as per setup done
- in requestPermissionsWithSettings()). */
- double triggerIntervalSec = 0.; /**< Optional: specifies number of seconds before the notification should trigger. */
- bool repeat = false; /**< Optional: allows the notification to continuously retrigger after
- triggerIntervalSec seconds. Available from iOS 10. */
-
- /**@}*/
-
- //==============================================================================
- /** @name Android only fields */
- /**@{*/
-
- String icon; /**< Required: name of an icon file (without an extension) to be used for
- this notification. This must be the name of one of the image
- files included into resources when exporting an Android project
- (see "Extra Android Raw Resources" setting in Projucer). */
-
- String channelId; /**< Required for Android API level 26 or above: specifies notification channel id. Refer to
- setupChannels(). Ignored on earlier Android versions. */
-
- Image largeIcon; /**< Optional: an additional large icon displayed in the notification content view. */
-
- String tickerText; /**< Optional: ticker text used for accessibility services. */
-
- Array<Action> actions; /**< Optional: actions associated with the notification. Note that the OS may allow only a limited
- number of actions to be presented, so always present most important actions first.
- Available from Android API 16 or above. */
-
- /** Used to represent a progress of some operation. */
- struct Progress
- {
- int max = 0; /**< Max possible value of a progress. A typical usecase is to set max to 100 and increment
- current's value as percentage complete. */
- int current = 0; /**< Current progress value, should be from 0 to max. */
- bool indeterminate = false; /**< If true, then the progress represents a continuing activity indicator with ongoing
- animation and no numeric value. */
- };
-
- Progress progress; /**< Optional: set to default (0, 0, false), to disable progress display. */
-
- /** Metadata that can be used by the OS to better handle the notification, depending on its priority. */
- enum Type
- {
- unspecified, /**< Category not set. */
- alarm, /**< Alarm or timer. */
- call, /**< Incoming voice/video call or similar. */
- email, /**< Async message like email. */
- error, /**< Error in background operation or authentication status. */
- event, /**< Calendar event. */
- message, /**< Incoming message (sms, instant message etc.). */
- taskProgress, /**< Progress for a long-running background operation. */
- promo, /**< Promotion or advertisement. */
- recommendation, /**< Specific, single thing related recommendation. */
- reminder, /**< User-scheduled reminder. */
- service, /**< Running background service. */
- social, /**< Social network or sharing update. */
- status, /**< Ongoing information about device or contextual status. */
- system, /**< System or device status update. */
- transport /**< Media transport control for playback. */
- };
-
- /** Metadata used as a hint to the OS about the priority of the notification. */
- enum Priority
- {
- veryLow = -2,
- low = -1,
- medium = 0,
- high = 1,
- veryHigh = 2
- };
-
- String person; /**< Optional: additional metadata used as a hint to OS that a notification is
- related to a specific person. Can be useful for instance messaging apps.
- Available from Android API 21 or above. */
-
- Type type = unspecified; /**< Optional. Available from Android API 21 or above. */
- Priority priority = medium; /**< Optional. Available from Android API 16 or above. */
-
- /** Describes how to show the notification when the screen is locked. Available from Android API 21 or above. */
- enum LockScreenAppearance
- {
- dontShow = -1, /**< The notification is not allowed on the lock screen */
- showPartially = 0, /**< Only some information is allowed on the lock screen */
- showCompletely = 1 /**< The entire notification is allowed on the lock screen */
- };
-
- LockScreenAppearance lockScreenAppearance = showPartially; /**< Optional. */
-
- std::unique_ptr<Notification> publicVersion; /**< Optional: if you set lockScreenAppearance to showPartially,
- then you can provide "public version" of your notification
- that will be displayed on the lock screen. This way you can
- control what information is visible when the screen is locked. */
-
- String groupSortKey; /**< Optional: Used to order notifications within the same group. Available from Android API 20 or above. */
- bool groupSummary = false; /**< Optional: if true, then this notification will be a group summary of the group set with groupId.
- Available from Android API 20 or above. */
-
- Colour accentColour; /**< Optional: sets accent colour. The default colour will be used if accentColour is not set.
- Available from Android API 21 or above. */
- Colour ledColour; /**< Optional: Sets the led colour. The hardware will do its best to approximate the colour.
- The default colour will be used if ledColour is not set. */
-
- /** Allows to control the time the device's led is on and off. */
- struct LedBlinkPattern
- {
- int msToBeOn = 0; /**< The led will be on for the given number of milliseconds, after which it will turn off. */
- int msToBeOff = 0; /**< The led will be off for the given number of milliseconds, after which it will turn on. */
- };
-
- LedBlinkPattern ledBlinkPattern; /**< Optional. */
-
- Array<int> vibrationPattern; /**< Optional: sets the vibration pattern in milliseconds. The first value indicates how long
- to wait until vibration starts. The second value indicates how long to vibrate. The third
- value will say how long to not vibrate and so on. For instance, if the pattern is:
- 1000, 2000, 3000, 4000 - then one second after receiving a notification the device will
- vibrate for two seconds, followed by 3 seconds of no vibration and finally, 4 seconds of
- vibration. */
-
- bool shouldAutoCancel = true; /**< Optional: If true, the notification will be automatically cancelled when a user clicks it in the panel. */
-
- bool localOnly = true; /**< Optional: whether or not the notification should bridge to other devices.
- Available from Android API 20 or above. */
-
- bool ongoing = false; /**< Optional: If true, then it cannot be dismissed by the user and it must be dismissed manually.
- Typically used for ongoing background tasks that the user is actively engaged with. To
- dismiss such notification, you need to call removeDeliveredNotification() or
- removeAllDeliveredNotifications(). */
-
- bool alertOnlyOnce = false; /**< Optional: Set this flag if you would only like the sound, vibrate and ticker to be played if the notification
- is not already showing. */
-
- /** Controls timestamp visibility and format. */
- enum TimestampVisibility
- {
- off, /**< Do not show timestamp. */
- normal, /**< Show normal timestamp. */
- chronometer, /**< Show chronometer as a stopwatch. Available from Android API 16 or above. */
- countDownChronometer /**< Set the chronometer to count down instead of counting up. Available from Android API 24 or above.*/
- };
-
- TimestampVisibility timestampVisibility = normal; /**< Optional. */
-
- /** Controls badge icon type to use if a notification is shown as a badge. Available from Android API 26 or above. */
- enum BadgeIconType
- {
- none,
- small,
- large
- };
-
- BadgeIconType badgeIconType = large;
-
- /** Controls sound and vibration behaviour for group notifications. Available from Android API 26 or above. */
- enum GroupAlertBehaviour
- {
- alertAll, /**< both child notifications and group notifications should produce sound and vibration. */
- AlertSummary, /**< all child notifications in the group should have no sound nor vibration, even
- if corresponding notification channel has sounds and vibrations enabled. */
- AlertChildren /**< summary notifications in the group should have no sound nor vibration, even if
- corresponding notification channel has sounds and vibrations enabled. */
- };
-
- GroupAlertBehaviour groupAlertBehaviour = alertAll;
-
- int timeoutAfterMs = 0; /**< specifies a duration in milliseconds, after which the notification should be
- cancelled, if it is not already cancelled. Available from Android API 26 or above. */
- /**@}*/
- };
-
-
- //==============================================================================
- /** Describes settings we want to use for current device. Note that at the
- moment this is only used on iOS and partially on OSX.
-
- On OSX only allow* flags are used and they control remote notifications only.
- To control sound, alert and badge settings for local notifications on OSX,
- use Notifications settings in System Preferences.
-
- To setup push notifications for current device, provide permissions required,
- as well as register categories of notifications you want to support. Each
- category needs to have a unique identifier and it can optionally have multiple
- actions. Each action also needs to have a unique identifier. The example setup
- may look as follows:
-
- @code
-
- using Action = PushNotifications::Settings::Action;
- using Category = PushNotifications::Settings::Category;
-
- Action okAction;
- okAction.identifier = "okAction";
- okAction.title = "OK!";
- okAction.style = Action::button;
- okAction.triggerInBackground = true;
-
- Action cancelAction;
- cancelAction.identifier = "cancelAction";
- cancelAction.title = "Cancel";
- cancelAction.style = Action::button;
- cancelAction.triggerInBackground = true;
- cancelAction.destructive = true;
-
- Action textAction;
- textAction.identifier = "textAction";
- textAction.title = "Enter text";
- textAction.style = Action::text;
- textAction.triggerInBackground = true;
- textAction.destructive = false;
- textAction.textInputButtonText = "Ok";
- textAction.textInputPlaceholder = "Enter text...";
-
- Category okCategory;
- okCategory.identifier = "okCategory";
- okCategory.actions = { okAction };
-
- Category okCancelCategory;
- okCancelCategory.identifier = "okCancelCategory";
- okCancelCategory.actions = { okAction, cancelAction };
-
- Category textCategory;
- textCategory.identifier = "textCategory";
- textCategory.actions = { textAction };
- textCategory.sendDismissAction = true;
-
- PushNotifications::Settings settings;
- settings.allowAlert = true;
- settings.allowBadge = true;
- settings.allowSound = true;
- settings.categories = { okCategory, okCancelCategory, textCategory };
-
- @endcode
- */
- struct Settings
- {
- using Action = Notification::Action;
-
- /** Describes a category of a notification. Each category has a unique identifier
- and a list of associated actions.
- Note that the OS may allow only a limited number of actions to be presented, so
- always present most important actions first.
- */
- struct Category
- {
- juce::String identifier; /**< unique identifier */
- juce::Array<Action> actions; /**< optional list of actions within this category */
- bool sendDismissAction = false; /**< whether dismiss action will be sent to the app (from iOS 10 only) */
- };
-
- bool allowSound = false; /**< whether the app should play a sound upon notification */
- bool allowAlert = false; /**< whether the app should present an alert upon notification */
- bool allowBadge = false; /**< whether the app may badge its icon upon notification */
- Array<Category> categories; /**< list of categories the app wants to support */
- };
-
- /** Initialises push notifications on current device with the settings provided.
- Call this on your application startup and on iOS the first time the application starts,
- a user will be presented with a permission request dialog to give push notifications permission.
- Once a user responds, Listener::notificationSettingsReceived() will be called so that
- you can check what permissions where actually granted. The listener callback will be called
- on each subsequent startup too (provided you called requestPermissionsWithSettings() on previous
- application run). This way you can check what are current push notifications permissions.
-
- Note that settings are currently only used on iOS. When calling on other platforms, Settings
- with no categories and all allow* flags set to true will be received in
- Listener::notificationSettingsReceived().
-
- You can also call requestSettingsUsed() to explicitly ask for current settings.
- */
- void requestPermissionsWithSettings (const Settings& settings);
-
- /** Sends an asynchronous request to retrieve current settings that are currently in use.
- These can be exactly the same as used in requestPermissionsWithSettings(), but depending
- on user's subsequent changes in OS settings, the actual current settings may be
- different (e.g. user might have later decided to disable sounds).
-
- Note that settings are currently only used on iOS and partially on OSX.
-
- On OSX, only allow* flags are used and they refer to remote notifications only. For
- local notifications, refer to System Preferences.
-
- When calling this function on other platforms, Settings with no categories and all allow*
- flags set to true will be received in Listener::notificationSettingsReceived().
- */
- void requestSettingsUsed();
-
- //==============================================================================
- /** Android API level 26 or higher only: Represents notification channel through which
- notifications will be sent. Starting from Android API level 26, you should call setupChannels()
- at the start of your application, before posting any notifications. Then, when sending notifications,
- assign a channel to each created notification.
- */
- struct Channel
- {
- String identifier; /**< Required: Unique channel identifier. */
- String name; /**< Required: User facing name of the channel. */
-
- /** Controls how interruptive the notification posted on this channel are. */
- enum Importance
- {
- none,
- min,
- low,
- normal,
- high,
- max
- };
-
- Importance importance = normal; /**< Required. */
- Notification::LockScreenAppearance lockScreenAppearance = Notification::showPartially; /**< Optional. */
-
- String description; /**< Optional: user visible description of the channel. */
- String groupId; /**< Required: group this channel belongs to (see ChannelGroup). */
- Colour ledColour; /**< Optional: sets the led colour for notifications in this channel. */
- bool bypassDoNotDisturb = false; /**< Optional: true if notifications in this channel can bypass do not disturb setting. */
- bool canShowBadge = false; /**< Optional: true if notifications in this channel can show badges in a Launcher application. */
- bool enableLights = false; /**< Optional: true if notifications in this channel should show lights (subject to hardware support). */
- bool enableVibration = false; /**< Optional: true if notifications in this channel should trigger vibrations. */
-
- URL soundToPlay; /**< Optional: sound to play in this channel. See Notification::soundToPlay for more info. */
- Array<int> vibrationPattern; /**< Optional: vibration pattern for this channel. See Notification::vibrationPattern for more info. */
- };
-
- /** Android API level 26 or higher only: represents a channel group. This allows for
- visual grouping of corresponding channels in notification settings presented to the user.
- At least one channel group has to be specified before notifications can be sent.
- */
- struct ChannelGroup
- {
- String identifier; /**< Required: Unique channel group identifier. */
- String name; /**< Required: User visible name of the channel group. */
- };
-
- /** Android API level 26 or higher only: configures notification channel groups and channels to be
- used in the app. These have to be setup before notifications can be sent on Android API
- level 26 or higher.
- */
- void setupChannels (const Array<ChannelGroup>& groups, const Array<Channel>& channels);
-
- //==============================================================================
- /** iOS only: sends an asynchronous request to retrieve a list of notifications that were
- scheduled and not yet delivered.
-
- When the list is retrieved, Listener::pendingLocalNotificationsListReceived() will be called.
- */
- void getPendingLocalNotifications() const;
-
- /** Unschedules a pending local notification with a given identifier. Available from iOS 10. */
- void removePendingLocalNotification (const String& identifier);
-
- /** Unschedules all pending local notifications. iOS only. */
- void removeAllPendingLocalNotifications();
-
- //==============================================================================
- /** Checks whether notifications are enabled for given application.
- On iOS and OSX this will always return true, use requestSettingsUsed() instead.
- */
- bool areNotificationsEnabled() const;
-
- /** On iOS as well as on Android, sends a local notification.
- On Android and iOS 10 or above, this will refresh an existing notification
- if the same identifier is used as in a notification that was already sent
- and not yet responded by a user.
- */
- void sendLocalNotification (const Notification& notification);
-
- /** Sends a request for a list of notifications delivered. Such notifications are visible in the
- notification area on the device and they are still waiting for user action/response.
- When the request is finished Listener::deliveredNotificationsListReceived() will be called.
-
- On iOS, iOS version 10 or higher is required. On Android, API level 18 or higher is required.
- For unsupported platforms, Listener::deliveredNotificationsListReceived() will return an empty array.
- */
- void getDeliveredNotifications() const;
-
- /** Removes a previously delivered notification. This can be useful for instance when the
- information in the notification becomes obsolete.
- */
- void removeDeliveredNotification (const String& identifier);
-
- /** Removes all notifications that were delivered. */
- void removeAllDeliveredNotifications();
-
- //==============================================================================
- /** Retrieves current device token. Note, it is not a good idea to cache this token
- because it may change in the meantime. Always call this method to get the current
- token value.
- */
- String getDeviceToken() const;
-
- /** Android only: allows to subscribe to messages from a specific topic.
- So you could for instance subscribe this device to all "sports" topic messages
- to receive any remote notifications that have "sports" topic set.
- Refer to Firebase documentation for how to send topic messages.
- */
- void subscribeToTopic (const String& topic);
-
- /** Android only: allows to remove a topic subscription that was previously added with
- subscribeToTopic().
- */
- void unsubscribeFromTopic (const String& topic);
-
- /** Android only: sends an upstream message to your app server. The server must implement
- XMPP Connection Server protocol (refer to Firebase documentation).
-
- @param serverSenderId Represents the sender. Consult your Firebase project
- settings to retrieve the sender id.
-
- @param collapseKey Remote messages with the same collapse key that were not
- yet delivered will be collapsed into one, with the
- newest message replacing all the previous ones.
- Note that there may be a limit of maximum collapse keys
- used at the same time and beyond the limit (refer to
- Firebase documentation) it is not guaranteed which keys
- will be in use by the server.
-
- @param messageId A unique message ID. Used in error callbacks and debugging.
-
- @param messageType Message type.
-
- @param timeToLive TTL in seconds. If 0, the message sending will be attempted
- immediately and it will be dropped if the device is not
- connected. Otherwise, the message will be queued for the
- period specified.
-
- @param additionalData Collection of key-value pairs to be used as an additional
- data for the message.
- */
- void sendUpstreamMessage (const String& serverSenderId,
- const String& collapseKey,
- const String& messageId,
- const String& messageType,
- int timeToLive,
- const StringPairArray& additionalData);
-
- //==============================================================================
- /** Register a listener (ideally on application startup) to receive information about
- notifications received and any callbacks to async functions called.
- */
- struct Listener
- {
- virtual ~Listener() = default;
-
- /** This callback will be called after you call requestSettingsUsed() or
- requestPermissionsWithSettings().
-
- Note that settings are currently only used on iOS. When called on other platforms, Settings
- with no categories and all allow flags set to true will be received in
- Listener::notificationSettingsReceived().
- */
- virtual void notificationSettingsReceived (const Settings& settings) { ignoreUnused (settings); }
-
- /** Called when the list of pending notifications, requested by calling
- getPendingLocalNotifications() is returned. iOS 10 or above only.
- */
- virtual void pendingLocalNotificationsListReceived (const Array<Notification>& notifications) { ignoreUnused (notifications); }
-
- /** This can be called in multiple different situations, depending on the OS and the situation.
-
- On pre iOS 10 device it will be called when a user presses on a notification or when a
- notification was received when the app was in the foreground already. On iOS 10 it will be
- called when a user presses on a notification
-
- Note: On Android, if remote notification was received while the app was in the background and
- then user pressed on it, the notification object received in this callback will contain only
- "properties" member set. Hence, if you want to know what was the notification title, content
- etc, you need to set them as additional properties, so that you will be able to restore them
- from "properties" dictionary.
-
- Note you can receive this callback on startup, if the application was launched from a notification.
- */
- virtual void handleNotification (bool isLocalNotification, const Notification& notification) { ignoreUnused (isLocalNotification); ignoreUnused (notification); }
-
- /** This can be called when a user performs some action on the notification such as
- pressing on an action button or responding with a text input.
- Note that pressing on a notification area, i.e. not on an action button is not considered
- to be an action, and hence receivedNotification() will be called in that case.
-
- Note you can receive this callback on startup, if the application was launched from a notification's action.
-
- @param isLocalNotification If the notification is local
- @param notification The notification
- @param actionIdentifier A String identifying the action
- @param optionalResponse Text response a user inputs for notifications with a text input.
- Empty for notifications without a text input option.
-
- */
- virtual void handleNotificationAction (bool isLocalNotification,
- const Notification& notification,
- const String& actionIdentifier,
- const String& optionalResponse)
- {
- ignoreUnused (isLocalNotification);
- ignoreUnused (notification);
- ignoreUnused (actionIdentifier);
- ignoreUnused (optionalResponse);
- }
-
- /** For iOS10 and Android, this can be also called when a user dismissed the notification before
- responding to it.
- */
- virtual void localNotificationDismissedByUser (const Notification& notification) { ignoreUnused (notification); }
-
- /** Called after getDeliveredNotifications() request is fulfilled. Returns notifications
- that are visible in the notification area on the device and that are still waiting
- for a user action/response.
-
- On iOS, iOS version 10 or higher is required. On Android, API level 18 or higher is required.
- For unsupported platforms, an empty array will be returned.
- */
- virtual void deliveredNotificationsListReceived (const Array<Notification>& notifications) { ignoreUnused (notifications); }
-
- /** Called whenever a token gets refreshed. You should monitor any token updates, because
- only the last token that is assigned to device is valid and can be used.
- */
- virtual void deviceTokenRefreshed (const String& token) { ignoreUnused (token); }
-
- /** Called when Firebase Cloud Messaging server deletes pending messages. This can happen when
- 1) too many messages were sent to the server (hint: use collapsible messages).
- 2) the devices hasn't been online in a long time (refer to Firebase documentation for
- the maximum time a message can be stored on FCM before expiring).
- */
- virtual void remoteNotificationsDeleted() {}
-
- /** Called when an upstream message sent with PushNotifications::sendUpstreamMessage() has been
- sent successfully.
- Bear in mind that in may take several minutes or more to receive this callback.
- */
- virtual void upstreamMessageSent (const String& messageId) { ignoreUnused (messageId); }
-
- /** Called when there was an error sending an upstream message with
- PushNotifications::sendUpstreamMessage().
- Bear in mind that in may take several minutes or more to receive this callback.
- */
- virtual void upstreamMessageSendingError (const String& messageId, const String& error) { ignoreUnused (messageId); ignoreUnused (error); }
- };
-
- void addListener (Listener* l);
- void removeListener (Listener* l);
-
- private:
- PushNotifications();
- ~PushNotifications() override;
-
- ListenerList<PushNotifications::Listener> listeners;
-
- #if JUCE_ANDROID
- friend bool juce_handleNotificationIntent (void*);
-
- friend struct JuceFirebaseInstanceIdService;
- friend struct JuceFirebaseMessagingService;
- #endif
-
- #if JUCE_PUSH_NOTIFICATIONS
- struct Pimpl;
- friend struct Pimpl;
-
- std::unique_ptr<Pimpl> pimpl;
- #endif
- };
-
- } // namespace juce
|