| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE 6 technical preview.
 -    Copyright (c) 2017 - ROLI Ltd.
 - 
 -    You may use this code under the terms of the GPL v3
 -    (see www.gnu.org/licenses).
 - 
 -    For this technical preview, this file is not subject to commercial licensing.
 - 
 -    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 canceled. 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
 
 
  |