Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

juce_PushNotifications.h 39KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE 6 technical preview.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. You may use this code under the terms of the GPL v3
  6. (see www.gnu.org/licenses).
  7. For this technical preview, this file is not subject to commercial licensing.
  8. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  9. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  10. DISCLAIMED.
  11. ==============================================================================
  12. */
  13. #pragma once
  14. namespace juce
  15. {
  16. /** Singleton class responsible for push notifications functionality. Both remote and
  17. local notifications are supported. To get information about notifications,
  18. register a listener on your application startup. It is best to register the
  19. listener as soon as possible, because your application can be launched from
  20. a push notification too.
  21. To send a local notification create an instance of Notification, fill the necessary
  22. fields and call PushNotifications::sendLocalNotification(). When receiving local or
  23. remote notifications, inspect the Notification's fields for notification details.
  24. Bear in mind that some fields will not be available when receiving a remote
  25. notification.
  26. @tags{GUI}
  27. */
  28. class JUCE_API PushNotifications : private DeletedAtShutdown
  29. {
  30. public:
  31. #ifndef DOXYGEN
  32. JUCE_DECLARE_SINGLETON (PushNotifications, false)
  33. #endif
  34. //==============================================================================
  35. /** Represents a notification that can be sent or received. */
  36. struct Notification
  37. {
  38. Notification() = default;
  39. Notification (const Notification& other);
  40. /** Checks whether a given notification is correctly configured for a given OS. */
  41. bool isValid() const noexcept;
  42. /** Represents an action on a notification that can be presented as a button or a text input.
  43. On Android, each notification has its action specified explicitly, on iOS you configure an
  44. allowed set of actions on startup and pack them into categories (see Settings).
  45. */
  46. struct Action
  47. {
  48. /** Controls the appearance of this action. */
  49. enum Style
  50. {
  51. button, /**< Show this action as a button. */
  52. text /**< Show this action as a text input field (on Android API 20 or higher is required). */
  53. };
  54. /** @name Common fields */
  55. /**@{*/
  56. Style style = button;
  57. String title; /**< Required. the name of the action displayed to the user. */
  58. String textInputPlaceholder; /**< Optional: placeholder text for text input notification.
  59. Note that it will be ignored if button style is used. */
  60. var parameters; /**< Optional: additional parameters that can be passed. */
  61. /**@}*/
  62. /** @name iOS only fields */
  63. /**@{*/
  64. String identifier; /**< Required: unique identifier. This should be one of the
  65. identifiers set with requestPermissionsWithSettings(). */
  66. bool triggerInBackground = false; /**< Whether the app can process the action in background. */
  67. bool destructive = false; /**< Whether to display the action as destructive. */
  68. String textInputButtonText; /**< Optional: Text displayed on text input notification
  69. button (from iOS 10 only).
  70. Note that it will be ignored if style is set to Style::button. */
  71. /**@}*/
  72. /** @name Android only fields */
  73. /**@{*/
  74. String icon; /**< Optional: name of an icon file (without an extension) to be used for
  75. this action. This must be the name of one of the image
  76. files included into resources when exporting an Android project
  77. (see "Extra Android Raw Resources" setting in Projucer).
  78. Note that not all Android versions support an icon for an action, though
  79. it is recommended to provide it nevertheless. */
  80. StringArray allowedResponses; /**< Optional: a list of possible answers if the answer set is limited.
  81. When left empty, then the user will be able to input any text. */
  82. /**@}*/
  83. };
  84. //==============================================================================
  85. /** @name Common fields */
  86. /**@{*/
  87. String identifier; /**< Required: unique id that can be used to later dismiss the notification
  88. (on iOS available from version 10). */
  89. String title; /**< Required: the title of the notification, usually displayed in the first row. */
  90. String body; /**< Required: the content of the notification, usually displayed in the second row. */
  91. String subtitle; /**< Optional: additional text, that may be displayed e.g. in the third row or in the header
  92. area. Note that on Android, depending on OS version, this may fight for
  93. space with other components of the notification, so use this field
  94. judiciously. On iOS available from version 10. On Android available from API 16. */
  95. String groupId; /**< Optional: allows the OS to visually group, collapse, and expand a set of notifications,
  96. note that OS may automatically group notifications if no groupId is specified.
  97. Available on Android API 20 or above and iOS 10 or above. */
  98. int badgeNumber = 0; /**< Optional: on platforms that support it, can set a number this notification represents. */
  99. URL soundToPlay; /**< Optional: empty when the notification should be silent. When the name is set to
  100. "default_os_sound", then a default sound will be used.
  101. For a custom sound on OSX, set the URL to the name of a sound file (preferably without
  102. an extension) and place the sound file directly in bundle's "Resources" directory (you
  103. can use "Xcode Resource" tickbox in Projucer to achieve that), i.e. it cannot be in a
  104. subdirectory of "Resources" like "Resources/sound". Alternatively, if a sound file
  105. cannot be found in bundle's "Resources" directory, the OS may look for the sound in the
  106. following paths: "~/Library/Sounds", "/Library/Sounds", "/Network/Library/Sounds",
  107. "/System/Library/Sounds".
  108. For a custom sound on iOS, set the URL to a relative path within your bundle, including
  109. file extension. For instance, if your bundle contains "sounds" folder with "my_sound.caf"
  110. file, then the URL should be "sounds/my_sound.caf".
  111. For a custom sound on Android, set URL to the name of a raw resource file
  112. (without an extension) that was included when exporting an Android project in
  113. Projucer (see "Extra Android Raw Resources" setting). */
  114. var properties; /**< Optional: collection of additional properties that may be passed as a dictionary. */
  115. /**@}*/
  116. //==============================================================================
  117. /** @name iOS only fields */
  118. /**@{*/
  119. String category; /**< Required: determines set of actions that will appear (as per setup done
  120. in requestPermissionsWithSettings()). */
  121. double triggerIntervalSec = 0.; /**< Optional: specifies number of seconds before the notification should trigger. */
  122. bool repeat = false; /**< Optional: allows the notification to continuously retrigger after
  123. triggerIntervalSec seconds. Available from iOS 10. */
  124. /**@}*/
  125. //==============================================================================
  126. /** @name Android only fields */
  127. /**@{*/
  128. String icon; /**< Required: name of an icon file (without an extension) to be used for
  129. this notification. This must be the name of one of the image
  130. files included into resources when exporting an Android project
  131. (see "Extra Android Raw Resources" setting in Projucer). */
  132. String channelId; /**< Required for Android API level 26 or above: specifies notification channel id. Refer to
  133. setupChannels(). Ignored on earlier Android versions. */
  134. Image largeIcon; /**< Optional: an additional large icon displayed in the notification content view. */
  135. String tickerText; /**< Optional: ticker text used for accessibility services. */
  136. Array<Action> actions; /**< Optional: actions associated with the notification. Note that the OS may allow only a limited
  137. number of actions to be presented, so always present most important actions first.
  138. Available from Android API 16 or above. */
  139. /** Used to represent a progress of some operation. */
  140. struct Progress
  141. {
  142. int max = 0; /**< Max possible value of a progress. A typical usecase is to set max to 100 and increment
  143. current's value as percentage complete. */
  144. int current = 0; /**< Current progress value, should be from 0 to max. */
  145. bool indeterminate = false; /**< If true, then the progress represents a continuing activity indicator with ongoing
  146. animation and no numeric value. */
  147. };
  148. Progress progress; /**< Optional: set to default (0, 0, false), to disable progress display. */
  149. /** Metadata that can be used by the OS to better handle the notification, depending on its priority. */
  150. enum Type
  151. {
  152. unspecified, /**< Category not set. */
  153. alarm, /**< Alarm or timer. */
  154. call, /**< Incoming voice/video call or similar. */
  155. email, /**< Async message like email. */
  156. error, /**< Error in background operation or authentication status. */
  157. event, /**< Calendar event. */
  158. message, /**< Incoming message (sms, instant message etc.). */
  159. taskProgress, /**< Progress for a long-running background operation. */
  160. promo, /**< Promotion or advertisement. */
  161. recommendation, /**< Specific, single thing related recommendation. */
  162. reminder, /**< User-scheduled reminder. */
  163. service, /**< Running background service. */
  164. social, /**< Social network or sharing update. */
  165. status, /**< Ongoing information about device or contextual status. */
  166. system, /**< System or device status update. */
  167. transport /**< Media transport control for playback. */
  168. };
  169. /** Metadata used as a hint to the OS about the priority of the notification. */
  170. enum Priority
  171. {
  172. veryLow = -2,
  173. low = -1,
  174. medium = 0,
  175. high = 1,
  176. veryHigh = 2
  177. };
  178. String person; /**< Optional: additional metadata used as a hint to OS that a notification is
  179. related to a specific person. Can be useful for instance messaging apps.
  180. Available from Android API 21 or above. */
  181. Type type = unspecified; /**< Optional. Available from Android API 21 or above. */
  182. Priority priority = medium; /**< Optional. Available from Android API 16 or above. */
  183. /** Describes how to show the notification when the screen is locked. Available from Android API 21 or above. */
  184. enum LockScreenAppearance
  185. {
  186. dontShow = -1, /**< The notification is not allowed on the lock screen */
  187. showPartially = 0, /**< Only some information is allowed on the lock screen */
  188. showCompletely = 1 /**< The entire notification is allowed on the lock screen */
  189. };
  190. LockScreenAppearance lockScreenAppearance = showPartially; /**< Optional. */
  191. std::unique_ptr<Notification> publicVersion; /**< Optional: if you set lockScreenAppearance to showPartially,
  192. then you can provide "public version" of your notification
  193. that will be displayed on the lock screen. This way you can
  194. control what information is visible when the screen is locked. */
  195. String groupSortKey; /**< Optional: Used to order notifications within the same group. Available from Android API 20 or above. */
  196. bool groupSummary = false; /**< Optional: if true, then this notification will be a group summary of the group set with groupId.
  197. Available from Android API 20 or above. */
  198. Colour accentColour; /**< Optional: sets accent colour. The default colour will be used if accentColour is not set.
  199. Available from Android API 21 or above. */
  200. Colour ledColour; /**< Optional: Sets the led colour. The hardware will do its best to approximate the colour.
  201. The default colour will be used if ledColour is not set. */
  202. /** Allows to control the time the device's led is on and off. */
  203. struct LedBlinkPattern
  204. {
  205. int msToBeOn = 0; /**< The led will be on for the given number of milliseconds, after which it will turn off. */
  206. int msToBeOff = 0; /**< The led will be off for the given number of milliseconds, after which it will turn on. */
  207. };
  208. LedBlinkPattern ledBlinkPattern; /**< Optional. */
  209. Array<int> vibrationPattern; /**< Optional: sets the vibration pattern in milliseconds. The first value indicates how long
  210. to wait until vibration starts. The second value indicates how long to vibrate. The third
  211. value will say how long to not vibrate and so on. For instance, if the pattern is:
  212. 1000, 2000, 3000, 4000 - then one second after receiving a notification the device will
  213. vibrate for two seconds, followed by 3 seconds of no vibration and finally, 4 seconds of
  214. vibration. */
  215. bool shouldAutoCancel = true; /**< Optional: If true, the notification will be automatically cancelled when a user clicks it in the panel. */
  216. bool localOnly = true; /**< Optional: whether or not the notification should bridge to other devices.
  217. Available from Android API 20 or above. */
  218. bool ongoing = false; /**< Optional: If true, then it cannot be dismissed by the user and it must be dismissed manually.
  219. Typically used for ongoing background tasks that the user is actively engaged with. To
  220. dismiss such notification, you need to call removeDeliveredNotification() or
  221. removeAllDeliveredNotifications(). */
  222. bool alertOnlyOnce = false; /**< Optional: Set this flag if you would only like the sound, vibrate and ticker to be played if the notification
  223. is not already showing. */
  224. /** Controls timestamp visibility and format. */
  225. enum TimestampVisibility
  226. {
  227. off, /**< Do not show timestamp. */
  228. normal, /**< Show normal timestamp. */
  229. chronometer, /**< Show chronometer as a stopwatch. Available from Android API 16 or above. */
  230. countDownChronometer /**< Set the chronometer to count down instead of counting up. Available from Android API 24 or above.*/
  231. };
  232. TimestampVisibility timestampVisibility = normal; /**< Optional. */
  233. /** Controls badge icon type to use if a notification is shown as a badge. Available from Android API 26 or above. */
  234. enum BadgeIconType
  235. {
  236. none,
  237. small,
  238. large
  239. };
  240. BadgeIconType badgeIconType = large;
  241. /** Controls sound and vibration behaviour for group notifications. Available from Android API 26 or above. */
  242. enum GroupAlertBehaviour
  243. {
  244. alertAll, /**< both child notifications and group notifications should produce sound and vibration. */
  245. AlertSummary, /**< all child notifications in the group should have no sound nor vibration, even
  246. if corresponding notification channel has sounds and vibrations enabled. */
  247. AlertChildren /**< summary notifications in the group should have no sound nor vibration, even if
  248. corresponding notification channel has sounds and vibrations enabled. */
  249. };
  250. GroupAlertBehaviour groupAlertBehaviour = alertAll;
  251. int timeoutAfterMs = 0; /**< specifies a duration in milliseconds, after which the notification should be
  252. cancelled, if it is not already canceled. Available from Android API 26 or above. */
  253. /**@}*/
  254. };
  255. //==============================================================================
  256. /** Describes settings we want to use for current device. Note that at the
  257. moment this is only used on iOS and partially on OSX.
  258. On OSX only allow* flags are used and they control remote notifications only.
  259. To control sound, alert and badge settings for local notifications on OSX,
  260. use Notifications settings in System Preferences.
  261. To setup push notifications for current device, provide permissions required,
  262. as well as register categories of notifications you want to support. Each
  263. category needs to have a unique identifier and it can optionally have multiple
  264. actions. Each action also needs to have a unique identifier. The example setup
  265. may look as follows:
  266. @code
  267. using Action = PushNotifications::Settings::Action;
  268. using Category = PushNotifications::Settings::Category;
  269. Action okAction;
  270. okAction.identifier = "okAction";
  271. okAction.title = "OK!";
  272. okAction.style = Action::button;
  273. okAction.triggerInBackground = true;
  274. Action cancelAction;
  275. cancelAction.identifier = "cancelAction";
  276. cancelAction.title = "Cancel";
  277. cancelAction.style = Action::button;
  278. cancelAction.triggerInBackground = true;
  279. cancelAction.destructive = true;
  280. Action textAction;
  281. textAction.identifier = "textAction";
  282. textAction.title = "Enter text";
  283. textAction.style = Action::text;
  284. textAction.triggerInBackground = true;
  285. textAction.destructive = false;
  286. textAction.textInputButtonText = "Ok";
  287. textAction.textInputPlaceholder = "Enter text...";
  288. Category okCategory;
  289. okCategory.identifier = "okCategory";
  290. okCategory.actions = { okAction };
  291. Category okCancelCategory;
  292. okCancelCategory.identifier = "okCancelCategory";
  293. okCancelCategory.actions = { okAction, cancelAction };
  294. Category textCategory;
  295. textCategory.identifier = "textCategory";
  296. textCategory.actions = { textAction };
  297. textCategory.sendDismissAction = true;
  298. PushNotifications::Settings settings;
  299. settings.allowAlert = true;
  300. settings.allowBadge = true;
  301. settings.allowSound = true;
  302. settings.categories = { okCategory, okCancelCategory, textCategory };
  303. @endcode
  304. */
  305. struct Settings
  306. {
  307. using Action = Notification::Action;
  308. /** Describes a category of a notification. Each category has a unique identifier
  309. and a list of associated actions.
  310. Note that the OS may allow only a limited number of actions to be presented, so
  311. always present most important actions first.
  312. */
  313. struct Category
  314. {
  315. juce::String identifier; /**< unique identifier */
  316. juce::Array<Action> actions; /**< optional list of actions within this category */
  317. bool sendDismissAction = false; /**< whether dismiss action will be sent to the app (from iOS 10 only) */
  318. };
  319. bool allowSound = false; /**< whether the app should play a sound upon notification */
  320. bool allowAlert = false; /**< whether the app should present an alert upon notification */
  321. bool allowBadge = false; /**< whether the app may badge its icon upon notification */
  322. Array<Category> categories; /**< list of categories the app wants to support */
  323. };
  324. /** Initialises push notifications on current device with the settings provided.
  325. Call this on your application startup and on iOS the first time the application starts,
  326. a user will be presented with a permission request dialog to give push notifications permission.
  327. Once a user responds, Listener::notificationSettingsReceived() will be called so that
  328. you can check what permissions where actually granted. The listener callback will be called
  329. on each subsequent startup too (provided you called requestPermissionsWithSettings() on previous
  330. application run). This way you can check what are current push notifications permissions.
  331. Note that settings are currently only used on iOS. When calling on other platforms, Settings
  332. with no categories and all allow* flags set to true will be received in
  333. Listener::notificationSettingsReceived().
  334. You can also call requestSettingsUsed() to explicitly ask for current settings.
  335. */
  336. void requestPermissionsWithSettings (const Settings& settings);
  337. /** Sends an asynchronous request to retrieve current settings that are currently in use.
  338. These can be exactly the same as used in requestPermissionsWithSettings(), but depending
  339. on user's subsequent changes in OS settings, the actual current settings may be
  340. different (e.g. user might have later decided to disable sounds).
  341. Note that settings are currently only used on iOS and partially on OSX.
  342. On OSX, only allow* flags are used and they refer to remote notifications only. For
  343. local notifications, refer to System Preferences.
  344. When calling this function on other platforms, Settings with no categories and all allow*
  345. flags set to true will be received in Listener::notificationSettingsReceived().
  346. */
  347. void requestSettingsUsed();
  348. //==============================================================================
  349. /** Android API level 26 or higher only: Represents notification channel through which
  350. notifications will be sent. Starting from Android API level 26, you should call setupChannels()
  351. at the start of your application, before posting any notifications. Then, when sending notifications,
  352. assign a channel to each created notification.
  353. */
  354. struct Channel
  355. {
  356. String identifier; /**< Required: Unique channel identifier. */
  357. String name; /**< Required: User facing name of the channel. */
  358. /** Controls how interruptive the notification posted on this channel are. */
  359. enum Importance
  360. {
  361. none,
  362. min,
  363. low,
  364. normal,
  365. high,
  366. max
  367. };
  368. Importance importance = normal; /**< Required. */
  369. Notification::LockScreenAppearance lockScreenAppearance = Notification::showPartially; /**< Optional. */
  370. String description; /**< Optional: user visible description of the channel. */
  371. String groupId; /**< Required: group this channel belongs to (see ChannelGroup). */
  372. Colour ledColour; /**< Optional: sets the led colour for notifications in this channel. */
  373. bool bypassDoNotDisturb = false; /**< Optional: true if notifications in this channel can bypass do not disturb setting. */
  374. bool canShowBadge = false; /**< Optional: true if notifications in this channel can show badges in a Launcher application. */
  375. bool enableLights = false; /**< Optional: true if notifications in this channel should show lights (subject to hardware support). */
  376. bool enableVibration = false; /**< Optional: true if notifications in this channel should trigger vibrations. */
  377. URL soundToPlay; /**< Optional: sound to play in this channel. See Notification::soundToPlay for more info. */
  378. Array<int> vibrationPattern; /**< Optional: vibration pattern for this channel. See Notification::vibrationPattern for more info. */
  379. };
  380. /** Android API level 26 or higher only: represents a channel group. This allows for
  381. visual grouping of corresponding channels in notification settings presented to the user.
  382. At least one channel group has to be specified before notifications can be sent.
  383. */
  384. struct ChannelGroup
  385. {
  386. String identifier; /**< Required: Unique channel group identifier. */
  387. String name; /**< Required: User visible name of the channel group. */
  388. };
  389. /** Android API level 26 or higher only: configures notification channel groups and channels to be
  390. used in the app. These have to be setup before notifications can be sent on Android API
  391. level 26 or higher.
  392. */
  393. void setupChannels (const Array<ChannelGroup>& groups, const Array<Channel>& channels);
  394. //==============================================================================
  395. /** iOS only: sends an asynchronous request to retrieve a list of notifications that were
  396. scheduled and not yet delivered.
  397. When the list is retrieved, Listener::pendingLocalNotificationsListReceived() will be called.
  398. */
  399. void getPendingLocalNotifications() const;
  400. /** Unschedules a pending local notification with a given identifier. Available from iOS 10. */
  401. void removePendingLocalNotification (const String& identifier);
  402. /** Unschedules all pending local notifications. iOS only. */
  403. void removeAllPendingLocalNotifications();
  404. //==============================================================================
  405. /** Checks whether notifications are enabled for given application.
  406. On iOS and OSX this will always return true, use requestSettingsUsed() instead.
  407. */
  408. bool areNotificationsEnabled() const;
  409. /** On iOS as well as on Android, sends a local notification.
  410. On Android and iOS 10 or above, this will refresh an existing notification
  411. if the same identifier is used as in a notification that was already sent
  412. and not yet responded by a user.
  413. */
  414. void sendLocalNotification (const Notification& notification);
  415. /** Sends a request for a list of notifications delivered. Such notifications are visible in the
  416. notification area on the device and they are still waiting for user action/response.
  417. When the request is finished Listener::deliveredNotificationsListReceived() will be called.
  418. On iOS, iOS version 10 or higher is required. On Android, API level 18 or higher is required.
  419. For unsupported platforms, Listener::deliveredNotificationsListReceived() will return an empty array.
  420. */
  421. void getDeliveredNotifications() const;
  422. /** Removes a previously delivered notification. This can be useful for instance when the
  423. information in the notification becomes obsolete.
  424. */
  425. void removeDeliveredNotification (const String& identifier);
  426. /** Removes all notifications that were delivered. */
  427. void removeAllDeliveredNotifications();
  428. //==============================================================================
  429. /** Retrieves current device token. Note, it is not a good idea to cache this token
  430. because it may change in the meantime. Always call this method to get the current
  431. token value.
  432. */
  433. String getDeviceToken() const;
  434. /** Android only: allows to subscribe to messages from a specific topic.
  435. So you could for instance subscribe this device to all "sports" topic messages
  436. to receive any remote notifications that have "sports" topic set.
  437. Refer to Firebase documentation for how to send topic messages.
  438. */
  439. void subscribeToTopic (const String& topic);
  440. /** Android only: allows to remove a topic subscription that was previously added with
  441. subscribeToTopic().
  442. */
  443. void unsubscribeFromTopic (const String& topic);
  444. /** Android only: sends an upstream message to your app server. The server must implement
  445. XMPP Connection Server protocol (refer to Firebase documentation).
  446. @param serverSenderId Represents the sender. Consult your Firebase project
  447. settings to retrieve the sender id.
  448. @param collapseKey Remote messages with the same collapse key that were not
  449. yet delivered will be collapsed into one, with the
  450. newest message replacing all the previous ones.
  451. Note that there may be a limit of maximum collapse keys
  452. used at the same time and beyond the limit (refer to
  453. Firebase documentation) it is not guaranteed which keys
  454. will be in use by the server.
  455. @param messageId A unique message ID. Used in error callbacks and debugging.
  456. @param messageType Message type.
  457. @param timeToLive TTL in seconds. If 0, the message sending will be attempted
  458. immediately and it will be dropped if the device is not
  459. connected. Otherwise, the message will be queued for the
  460. period specified.
  461. @param additionalData Collection of key-value pairs to be used as an additional
  462. data for the message.
  463. */
  464. void sendUpstreamMessage (const String& serverSenderId,
  465. const String& collapseKey,
  466. const String& messageId,
  467. const String& messageType,
  468. int timeToLive,
  469. const StringPairArray& additionalData);
  470. //==============================================================================
  471. /** Register a listener (ideally on application startup) to receive information about
  472. notifications received and any callbacks to async functions called.
  473. */
  474. struct Listener
  475. {
  476. virtual ~Listener() = default;
  477. /** This callback will be called after you call requestSettingsUsed() or
  478. requestPermissionsWithSettings().
  479. Note that settings are currently only used on iOS. When called on other platforms, Settings
  480. with no categories and all allow flags set to true will be received in
  481. Listener::notificationSettingsReceived().
  482. */
  483. virtual void notificationSettingsReceived (const Settings& settings) { ignoreUnused (settings); }
  484. /** Called when the list of pending notifications, requested by calling
  485. getPendingLocalNotifications() is returned. iOS 10 or above only.
  486. */
  487. virtual void pendingLocalNotificationsListReceived (const Array<Notification>& notifications) { ignoreUnused (notifications); }
  488. /** This can be called in multiple different situations, depending on the OS and the situation.
  489. On pre iOS 10 device it will be called when a user presses on a notification or when a
  490. notification was received when the app was in the foreground already. On iOS 10 it will be
  491. called when a user presses on a notification
  492. Note: On Android, if remote notification was received while the app was in the background and
  493. then user pressed on it, the notification object received in this callback will contain only
  494. "properties" member set. Hence, if you want to know what was the notification title, content
  495. etc, you need to set them as additional properties, so that you will be able to restore them
  496. from "properties" dictionary.
  497. Note you can receive this callback on startup, if the application was launched from a notification.
  498. */
  499. virtual void handleNotification (bool isLocalNotification, const Notification& notification) { ignoreUnused (isLocalNotification); ignoreUnused (notification); }
  500. /** This can be called when a user performs some action on the notification such as
  501. pressing on an action button or responding with a text input.
  502. Note that pressing on a notification area, i.e. not on an action button is not considered
  503. to be an action, and hence receivedNotification() will be called in that case.
  504. Note you can receive this callback on startup, if the application was launched from a notification's action.
  505. @param isLocalNotification If the notification is local
  506. @param notification The notification
  507. @param actionIdentifier A String identifying the action
  508. @param optionalResponse Text response a user inputs for notifications with a text input.
  509. Empty for notifications without a text input option.
  510. */
  511. virtual void handleNotificationAction (bool isLocalNotification,
  512. const Notification& notification,
  513. const String& actionIdentifier,
  514. const String& optionalResponse)
  515. {
  516. ignoreUnused (isLocalNotification);
  517. ignoreUnused (notification);
  518. ignoreUnused (actionIdentifier);
  519. ignoreUnused (optionalResponse);
  520. }
  521. /** For iOS10 and Android, this can be also called when a user dismissed the notification before
  522. responding to it.
  523. */
  524. virtual void localNotificationDismissedByUser (const Notification& notification) { ignoreUnused (notification); }
  525. /** Called after getDeliveredNotifications() request is fulfilled. Returns notifications
  526. that are visible in the notification area on the device and that are still waiting
  527. for a user action/response.
  528. On iOS, iOS version 10 or higher is required. On Android, API level 18 or higher is required.
  529. For unsupported platforms, an empty array will be returned.
  530. */
  531. virtual void deliveredNotificationsListReceived (const Array<Notification>& notifications) { ignoreUnused (notifications); }
  532. /** Called whenever a token gets refreshed. You should monitor any token updates, because
  533. only the last token that is assigned to device is valid and can be used.
  534. */
  535. virtual void deviceTokenRefreshed (const String& token) { ignoreUnused (token); }
  536. /** Called when Firebase Cloud Messaging server deletes pending messages. This can happen when
  537. 1) too many messages were sent to the server (hint: use collapsible messages).
  538. 2) the devices hasn't been online in a long time (refer to Firebase documentation for
  539. the maximum time a message can be stored on FCM before expiring).
  540. */
  541. virtual void remoteNotificationsDeleted() {}
  542. /** Called when an upstream message sent with PushNotifications::sendUpstreamMessage() has been
  543. sent successfully.
  544. Bear in mind that in may take several minutes or more to receive this callback.
  545. */
  546. virtual void upstreamMessageSent (const String& messageId) { ignoreUnused (messageId); }
  547. /** Called when there was an error sending an upstream message with
  548. PushNotifications::sendUpstreamMessage().
  549. Bear in mind that in may take several minutes or more to receive this callback.
  550. */
  551. virtual void upstreamMessageSendingError (const String& messageId, const String& error) { ignoreUnused (messageId); ignoreUnused (error); }
  552. };
  553. void addListener (Listener* l);
  554. void removeListener (Listener* l);
  555. private:
  556. PushNotifications();
  557. ~PushNotifications() override;
  558. ListenerList<PushNotifications::Listener> listeners;
  559. #if JUCE_ANDROID
  560. friend bool juce_handleNotificationIntent (void*);
  561. friend struct JuceFirebaseInstanceIdService;
  562. friend struct JuceFirebaseMessagingService;
  563. #endif
  564. #if JUCE_PUSH_NOTIFICATIONS
  565. struct Pimpl;
  566. friend struct Pimpl;
  567. std::unique_ptr<Pimpl> pimpl;
  568. #endif
  569. };
  570. } // namespace juce