688 lines
26 KiB
C++
688 lines
26 KiB
C++
// Copyright 2016 Google LLC
|
||
//
|
||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
// you may not use this file except in compliance with the License.
|
||
// You may obtain a copy of the License at
|
||
//
|
||
// http://www.apache.org/licenses/LICENSE-2.0
|
||
//
|
||
// Unless required by applicable law or agreed to in writing, software
|
||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
// See the License for the specific language governing permissions and
|
||
// limitations under the License.
|
||
|
||
#ifndef FIREBASE_MESSAGING_CLIENT_CPP_INCLUDE_FIREBASE_MESSAGING_H_
|
||
#define FIREBASE_MESSAGING_CLIENT_CPP_INCLUDE_FIREBASE_MESSAGING_H_
|
||
|
||
#include <stdint.h>
|
||
|
||
#include <map>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
#include "firebase/app.h"
|
||
#include "firebase/future.h"
|
||
#include "firebase/internal/common.h"
|
||
|
||
#if !defined(DOXYGEN) && !defined(SWIG)
|
||
FIREBASE_APP_REGISTER_CALLBACKS_REFERENCE(messaging)
|
||
#endif // !defined(DOXYGEN) && !defined(SWIG)
|
||
|
||
namespace firebase {
|
||
|
||
/// @brief Firebase Cloud Messaging API.
|
||
///
|
||
/// Firebase Cloud Messaging allows you to send data from your server to your
|
||
/// users' devices, and receive messages from devices on the same connection
|
||
/// if you're using a XMPP server.
|
||
///
|
||
/// The FCM service handles all aspects of queueing of messages and delivery
|
||
/// to client applications running on target devices.
|
||
namespace messaging {
|
||
|
||
/// @brief A class to configure the behavior of Firebase Cloud Messaging.
|
||
///
|
||
/// This class contains various configuration options that control some of
|
||
/// Firebase Cloud Messaging's behavior.
|
||
struct MessagingOptions {
|
||
/// Default constructor.
|
||
MessagingOptions() : suppress_notification_permission_prompt(false) {}
|
||
|
||
/// If true, do not display the prompt to the user requesting permission to
|
||
/// allow notifications to this app. If the prompt is suppressed in this way,
|
||
/// the developer must manually prompt the user for permission at some point
|
||
/// in the future using `RequestPermission()`.
|
||
///
|
||
/// If this prompt has already been accepted once in the past the prompt will
|
||
/// not be displayed again.
|
||
///
|
||
/// This option currently only applies to iOS.
|
||
bool suppress_notification_permission_prompt;
|
||
};
|
||
|
||
/// @brief Data structure for parameters that are unique to the Android
|
||
/// implementation.
|
||
struct AndroidNotificationParams {
|
||
/// The channel id that was provided when the message was sent.
|
||
std::string channel_id;
|
||
};
|
||
|
||
/// Used for messages that display a notification.
|
||
///
|
||
/// On android, this requires that the app is using the Play Services client
|
||
/// library.
|
||
struct Notification {
|
||
Notification() : android(nullptr) {}
|
||
|
||
/// Copy constructor. Makes a deep copy of this Message.
|
||
Notification(const Notification& other) : android(nullptr) { *this = other; }
|
||
|
||
/// Copy assignment operator. Makes a deep copy of this Message.
|
||
Notification& operator=(const Notification& other) {
|
||
this->title = other.title;
|
||
this->body = other.body;
|
||
this->icon = other.icon;
|
||
this->sound = other.sound;
|
||
this->tag = other.tag;
|
||
this->color = other.color;
|
||
this->click_action = other.click_action;
|
||
this->body_loc_key = other.body_loc_key;
|
||
this->body_loc_args = other.body_loc_args;
|
||
this->title_loc_key = other.title_loc_key;
|
||
this->title_loc_args = other.title_loc_args;
|
||
delete this->android;
|
||
if (other.android) {
|
||
this->android = new AndroidNotificationParams(*other.android);
|
||
} else {
|
||
this->android = nullptr;
|
||
}
|
||
return *this;
|
||
}
|
||
|
||
/// Destructor.
|
||
~Notification() { delete android; }
|
||
|
||
/// Indicates notification title. This field is not visible on iOS phones
|
||
/// and tablets.
|
||
std::string title;
|
||
|
||
/// Indicates notification body text.
|
||
std::string body;
|
||
|
||
/// Indicates notification icon. Sets value to myicon for drawable resource
|
||
/// myicon.
|
||
std::string icon;
|
||
|
||
/// Indicates a sound to play when the device receives the notification.
|
||
/// Supports default, or the filename of a sound resource bundled in the
|
||
/// app.
|
||
///
|
||
/// Android sound files must reside in /res/raw/, while iOS sound files
|
||
/// can be in the main bundle of the client app or in the Library/Sounds
|
||
/// folder of the app’s data container.
|
||
std::string sound;
|
||
|
||
/// Indicates the badge on the client app home icon. iOS only.
|
||
std::string badge;
|
||
|
||
/// Indicates whether each notification results in a new entry in the
|
||
/// notification drawer on Android. If not set, each request creates a new
|
||
/// notification. If set, and a notification with the same tag is already
|
||
/// being shown, the new notification replaces the existing one in the
|
||
/// notification drawer.
|
||
std::string tag;
|
||
|
||
/// Indicates color of the icon, expressed in \#rrggbb format. Android only.
|
||
std::string color;
|
||
|
||
/// The action associated with a user click on the notification.
|
||
///
|
||
/// On Android, if this is set, an activity with a matching intent filter is
|
||
/// launched when user clicks the notification.
|
||
///
|
||
/// If set on iOS, corresponds to category in APNS payload.
|
||
std::string click_action;
|
||
|
||
/// Indicates the key to the body string for localization.
|
||
///
|
||
/// On iOS, this corresponds to "loc-key" in APNS payload.
|
||
///
|
||
/// On Android, use the key in the app's string resources when populating this
|
||
/// value.
|
||
std::string body_loc_key;
|
||
|
||
/// Indicates the string value to replace format specifiers in body string
|
||
/// for localization.
|
||
///
|
||
/// On iOS, this corresponds to "loc-args" in APNS payload.
|
||
///
|
||
/// On Android, these are the format arguments for the string resource. For
|
||
/// more information, see [Formatting strings][1].
|
||
///
|
||
/// [1]:
|
||
/// https://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
|
||
std::vector<std::string> body_loc_args;
|
||
|
||
/// Indicates the key to the title string for localization.
|
||
///
|
||
/// On iOS, this corresponds to "title-loc-key" in APNS payload.
|
||
///
|
||
/// On Android, use the key in the app's string resources when populating this
|
||
/// value.
|
||
std::string title_loc_key;
|
||
|
||
/// Indicates the string value to replace format specifiers in title string
|
||
/// for localization.
|
||
///
|
||
/// On iOS, this corresponds to "title-loc-args" in APNS payload.
|
||
///
|
||
/// On Android, these are the format arguments for the string resource. For
|
||
/// more information, see [Formatting strings][1].
|
||
///
|
||
/// [1]:
|
||
/// https://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling
|
||
std::vector<std::string> title_loc_args;
|
||
|
||
/// Parameters that are unique to the Android implementation.
|
||
AndroidNotificationParams* android;
|
||
};
|
||
|
||
/// @brief Data structure used to send messages to, and receive messages from,
|
||
/// cloud messaging.
|
||
struct Message {
|
||
/// Initialize the message.
|
||
Message()
|
||
: time_to_live(0),
|
||
notification(nullptr),
|
||
notification_opened(false),
|
||
sent_time(0) {}
|
||
|
||
/// Destructor.
|
||
~Message() { delete notification; }
|
||
|
||
/// Copy constructor. Makes a deep copy of this Message.
|
||
Message(const Message& other) : notification(nullptr) { *this = other; }
|
||
|
||
/// Copy assignment operator. Makes a deep copy of this Message.
|
||
Message& operator=(const Message& other) {
|
||
this->from = other.from;
|
||
this->to = other.to;
|
||
this->collapse_key = other.collapse_key;
|
||
this->data = other.data;
|
||
this->raw_data = other.raw_data;
|
||
this->message_id = other.message_id;
|
||
this->message_type = other.message_type;
|
||
this->priority = other.priority;
|
||
this->original_priority = other.original_priority;
|
||
this->sent_time = other.sent_time;
|
||
this->time_to_live = other.time_to_live;
|
||
this->error = other.error;
|
||
this->error_description = other.error_description;
|
||
delete this->notification;
|
||
if (other.notification) {
|
||
this->notification = new Notification(*other.notification);
|
||
} else {
|
||
this->notification = nullptr;
|
||
}
|
||
this->notification_opened = other.notification_opened;
|
||
this->link = other.link;
|
||
return *this;
|
||
}
|
||
|
||
/// Authenticated ID of the sender. This is a project number in most cases.
|
||
///
|
||
/// Any value starting with google.com, goog. or gcm. are reserved.
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
std::string from;
|
||
|
||
/// This parameter specifies the recipient of a message.
|
||
///
|
||
/// For example it can be a registration token, a topic name, an Instance ID
|
||
/// or project ID.
|
||
///
|
||
/// For upstream messages use the format PROJECT_ID@gcm.googleapis.com.
|
||
///
|
||
/// This field is used for both upstream messages sent with
|
||
/// firebase::messaging::Send() and downstream messages received through
|
||
/// Listener::OnMessage(). For upstream messages,
|
||
/// PROJECT_ID@gcm.googleapis.com or Instance ID are accepted.
|
||
std::string to;
|
||
|
||
/// This parameter identifies a group of messages (e.g., with collapse_key:
|
||
/// "Updates Available") that can be collapsed, so that only the last message
|
||
/// gets sent when delivery can be resumed. This is intended to avoid sending
|
||
/// too many of the same messages when the device comes back online or becomes
|
||
/// active.
|
||
///
|
||
/// Note that there is no guarantee of the order in which messages get sent.
|
||
///
|
||
/// Note: A maximum of 4 different collapse keys is allowed at any given time.
|
||
/// This means a FCM connection server can simultaneously store 4 different
|
||
/// send-to-sync messages per client app. If you exceed this number, there is
|
||
/// no guarantee which 4 collapse keys the FCM connection server will keep.
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
std::string collapse_key;
|
||
|
||
/// The metadata, including all original key/value pairs. Includes some of the
|
||
/// HTTP headers used when sending the message. `gcm`, `google` and `goog`
|
||
/// prefixes are reserved for internal use.
|
||
///
|
||
/// This field is used for both upstream messages sent with
|
||
/// firebase::messaging::Send() and downstream messages received through
|
||
/// Listener::OnMessage().
|
||
std::map<std::string, std::string> data;
|
||
|
||
/// Binary payload. This field is currently unused.
|
||
std::string raw_data;
|
||
|
||
/// Message ID. This can be specified by sender. Internally a hash of the
|
||
/// message ID and other elements will be used for storage. The ID must be
|
||
/// unique for each topic subscription - using the same ID may result in
|
||
/// overriding the original message or duplicate delivery.
|
||
///
|
||
/// This field is used for both upstream messages sent with
|
||
/// firebase::messaging::Send() and downstream messages received through
|
||
/// Listener::OnMessage().
|
||
std::string message_id;
|
||
|
||
/// Equivalent with a content-type.
|
||
///
|
||
/// Defined values:
|
||
/// - "deleted_messages" - indicates the server had too many messages and
|
||
/// dropped some, and the client should sync with his own server.
|
||
/// Current limit is 100 messages stored.
|
||
/// - "send_event" - indicates an upstream message has been pushed to the
|
||
/// FCM server. It does not guarantee the upstream destination received
|
||
/// it.
|
||
/// Parameters: "message_id"
|
||
/// - "send_error" - indicates an upstream message expired, without being
|
||
/// sent to the FCM server.
|
||
/// Parameters: "message_id" and "error"
|
||
///
|
||
/// If this field is missing, the message is a regular message.
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
std::string message_type;
|
||
|
||
/// Sets the priority of the message. Valid values are "normal" and "high." On
|
||
/// iOS, these correspond to APNs priority 5 and 10.
|
||
///
|
||
/// By default, messages are sent with normal priority. Normal priority
|
||
/// optimizes the client app's battery consumption, and should be used unless
|
||
/// immediate delivery is required. For messages with normal priority, the app
|
||
/// may receive the message with unspecified delay.
|
||
///
|
||
/// When a message is sent with high priority, it is sent immediately, and the
|
||
/// app can wake a sleeping device and open a network connection to your
|
||
/// server.
|
||
///
|
||
/// For more information, see [Setting the priority of a message][1].
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
///
|
||
/// [1]:
|
||
/// https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message
|
||
std::string priority;
|
||
|
||
/// This parameter specifies how long (in seconds) the message should be kept
|
||
/// in FCM storage if the device is offline. The maximum time to live
|
||
/// supported is 4 weeks, and the default value is 4 weeks. For more
|
||
/// information, see [Setting the lifespan of a message][1].
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
///
|
||
/// [1]: https://firebase.google.com/docs/cloud-messaging/concept-options#ttl
|
||
int32_t time_to_live;
|
||
|
||
/// Error code. Used in "nack" messages for CCS, and in responses from the
|
||
/// server.
|
||
/// See the CCS specification for the externally-supported list.
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
std::string error;
|
||
|
||
/// Human readable details about the error.
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
std::string error_description;
|
||
|
||
/// Optional notification to show. This only set if a notification was
|
||
/// received with this message, otherwise it is null.
|
||
///
|
||
/// The notification is only guaranteed to be valid during the call to
|
||
/// Listener::OnMessage(). If you need to keep it around longer you will need
|
||
/// to make a copy of either the Message or Notification. Copying the Message
|
||
/// object implicitly makes a deep copy of the notification (allocated with
|
||
/// new) which is owned by the Message.
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
Notification* notification;
|
||
|
||
/// A flag indicating whether this message was opened by tapping a
|
||
/// notification in the OS system tray. If the message was received this way
|
||
/// this flag is set to true.
|
||
bool notification_opened;
|
||
|
||
/// The link into the app from the message.
|
||
///
|
||
/// This field is only used for downstream messages received through
|
||
/// Listener::OnMessage().
|
||
std::string link;
|
||
|
||
/// @cond FIREBASE_APP_INTERNAL
|
||
/// Original priority of the message.
|
||
std::string original_priority;
|
||
|
||
/// UTC timestamp in milliseconds when the message was sent.
|
||
/// See https://en.wikipedia.org/wiki/Unix_time for details of UTC.
|
||
int64_t sent_time;
|
||
/// @endcond
|
||
};
|
||
|
||
/// @brief Base class used to receive messages from Firebase Cloud Messaging.
|
||
///
|
||
/// You need to override base class methods to handle any events required by the
|
||
/// application. Methods are invoked asynchronously and may be invoked on other
|
||
/// threads.
|
||
class Listener {
|
||
public:
|
||
virtual ~Listener();
|
||
|
||
/// Called on the client when a message arrives.
|
||
///
|
||
/// @param[in] message The data describing this message.
|
||
virtual void OnMessage(const Message& message) = 0;
|
||
|
||
/// Called on the client when a registration token arrives. This function
|
||
/// will eventually be called in response to a call to
|
||
/// firebase::messaging::Initialize(...).
|
||
///
|
||
/// @param[in] token The registration token.
|
||
virtual void OnTokenReceived(const char* token) = 0;
|
||
};
|
||
|
||
/// @brief Initialize Firebase Cloud Messaging.
|
||
///
|
||
/// After Initialize is called, the implementation may call functions on the
|
||
/// Listener provided at any time.
|
||
///
|
||
/// @param[in] app The Firebase App object for this application.
|
||
/// @param[in] listener A Listener object that listens for events from the
|
||
/// Firebase Cloud Messaging servers.
|
||
///
|
||
/// @return kInitResultSuccess if initialization succeeded, or
|
||
/// kInitResultFailedMissingDependency on Android if Google Play services is
|
||
/// not available on the current device.
|
||
InitResult Initialize(const App& app, Listener* listener);
|
||
|
||
/// @brief Initialize Firebase Cloud Messaging.
|
||
///
|
||
/// After Initialize is called, the implementation may call functions on the
|
||
/// Listener provided at any time.
|
||
///
|
||
/// @param[in] app The Firebase App object for this application.
|
||
/// @param[in] listener A Listener object that listens for events from the
|
||
/// Firebase Cloud Messaging servers.
|
||
/// @param[in] options A set of options that configure the
|
||
/// initialzation behavior of Firebase Cloud Messaging.
|
||
///
|
||
/// @return kInitResultSuccess if initialization succeeded, or
|
||
/// kInitResultFailedMissingDependency on Android if Google Play services is
|
||
/// not available on the current device.
|
||
InitResult Initialize(const App& app, Listener* listener,
|
||
const MessagingOptions& options);
|
||
|
||
/// @brief Terminate Firebase Cloud Messaging.
|
||
///
|
||
/// Frees resources associated with Firebase Cloud Messaging.
|
||
///
|
||
/// @note On Android, the services will not be shut down by this method.
|
||
void Terminate();
|
||
|
||
/// Determines if automatic token registration during initalization is enabled.
|
||
///
|
||
/// @return true if auto token registration is enabled and false if disabled.
|
||
bool IsTokenRegistrationOnInitEnabled();
|
||
|
||
/// Enable or disable token registration during initialization of Firebase Cloud
|
||
/// Messaging.
|
||
///
|
||
/// This token is what identifies the user to Firebase, so disabling this avoids
|
||
/// creating any new identity and automatically sending it to Firebase, unless
|
||
/// consent has been granted.
|
||
///
|
||
/// If this setting is enabled, it triggers the token registration refresh
|
||
/// immediately. This setting is persisted across app restarts and overrides the
|
||
/// setting "firebase_messaging_auto_init_enabled" specified in your Android
|
||
/// manifest (on Android) or Info.plist (on iOS).
|
||
///
|
||
/// <p>By default, token registration during initialization is enabled.
|
||
///
|
||
/// The registration happens before you can programmatically disable it, so
|
||
/// if you need to change the default, (for example, because you want to prompt
|
||
/// the user before FCM generates/refreshes a registration token on app
|
||
/// startup), add to your application’s manifest:
|
||
///
|
||
///
|
||
/// @if NOT_DOXYGEN
|
||
/// <meta-data android:name="firebase_messaging_auto_init_enabled"
|
||
/// android:value="false" />
|
||
/// @else
|
||
/// @code
|
||
/// <meta-data android:name="firebase_messaging_auto_init_enabled"
|
||
/// android:value="false" />
|
||
/// @endcode
|
||
/// @endif
|
||
///
|
||
/// or on iOS to your Info.plist:
|
||
///
|
||
/// @if NOT_DOXYGEN
|
||
/// <key>FirebaseMessagingAutoInitEnabled</key>
|
||
/// <false/>
|
||
/// @else
|
||
/// @code
|
||
/// <key>FirebaseMessagingAutoInitEnabled</key>
|
||
/// <false/>
|
||
/// @endcode
|
||
/// @endif
|
||
///
|
||
/// @param enable sets if a registration token should be requested on
|
||
/// initialization.
|
||
void SetTokenRegistrationOnInitEnabled(bool enable);
|
||
|
||
/// @brief Set the listener for events from the Firebase Cloud Messaging
|
||
/// servers.
|
||
///
|
||
/// A listener must be set for the application to receive messages from
|
||
/// the Firebase Cloud Messaging servers. The implementation may call functions
|
||
/// on the Listener provided at any time.
|
||
///
|
||
/// @param[in] listener A Listener object that listens for events from the
|
||
/// Firebase Cloud Messaging servers.
|
||
///
|
||
/// @return Pointer to the previously set listener.
|
||
Listener* SetListener(Listener* listener);
|
||
|
||
/// Error code returned by Firebase Cloud Messaging C++ functions.
|
||
enum Error {
|
||
/// The operation was a success, no error occurred.
|
||
kErrorNone = 0,
|
||
/// Permission to receive notifications was not granted.
|
||
kErrorFailedToRegisterForRemoteNotifications,
|
||
/// Topic name is invalid for subscription/unsubscription.
|
||
kErrorInvalidTopicName,
|
||
/// Could not subscribe/unsubscribe because there is no registration token.
|
||
kErrorNoRegistrationToken,
|
||
/// Unknown error.
|
||
kErrorUnknown,
|
||
};
|
||
|
||
/// @brief Displays a prompt to the user requesting permission to display
|
||
/// notifications.
|
||
///
|
||
/// The permission prompt only appears on iOS. If the user has already agreed to
|
||
/// allow notifications, no prompt is displayed and the returned future is
|
||
/// completed immediately.
|
||
///
|
||
/// @return A future that completes when the notification prompt has been
|
||
/// dismissed.
|
||
Future<void> RequestPermission();
|
||
|
||
/// @brief Gets the result of the most recent call to RequestPermission();
|
||
///
|
||
/// @returns Result of the most recent call to RequestPermission().
|
||
Future<void> RequestPermissionLastResult();
|
||
|
||
/// Send an upstream ("device to cloud") message. You can only use the upstream
|
||
/// feature if your FCM implementation uses the XMPP-based Cloud Connection
|
||
/// Server. The current limits for max storage time and number of outstanding
|
||
/// messages per application are documented in the [FCM Developers Guide].
|
||
///
|
||
/// [FCM Developers Guide]: https://firebase.google.com/docs/cloud-messaging/
|
||
///
|
||
/// @param[in] message The message to send upstream.
|
||
void Send(const Message& message);
|
||
|
||
/// @brief Subscribe to receive all messages to the specified topic.
|
||
///
|
||
/// Subscribes an app instance to a topic, enabling it to receive messages
|
||
/// sent to that topic.
|
||
///
|
||
/// Call this function from the main thread. FCM is not thread safe.
|
||
///
|
||
/// @param[in] topic The name of the topic to subscribe. Must match the
|
||
/// following regular expression: `[a-zA-Z0-9-_.~%]{1,900}`.
|
||
Future<void> Subscribe(const char* topic);
|
||
|
||
/// @brief Gets the result of the most recent call to Unsubscribe();
|
||
///
|
||
/// @returns Result of the most recent call to Unsubscribe().
|
||
Future<void> SubscribeLastResult();
|
||
|
||
/// @brief Unsubscribe from a topic.
|
||
///
|
||
/// Unsubscribes an app instance from a topic, stopping it from receiving
|
||
/// any further messages sent to that topic.
|
||
///
|
||
/// Call this function from the main thread. FCM is not thread safe.
|
||
///
|
||
/// @param[in] topic The name of the topic to unsubscribe from. Must match the
|
||
/// following regular expression: `[a-zA-Z0-9-_.~%]{1,900}`.
|
||
Future<void> Unsubscribe(const char* topic);
|
||
|
||
/// @brief Gets the result of the most recent call to Unsubscribe();
|
||
///
|
||
/// @returns Result of the most recent call to Unsubscribe().
|
||
Future<void> UnsubscribeLastResult();
|
||
|
||
class PollableListenerImpl;
|
||
|
||
/// @brief A listener that can be polled to consume pending `Message`s.
|
||
///
|
||
/// This class is intended to be used with applications that have a main loop
|
||
/// that frequently updates, such as in the case of a game that has a main
|
||
/// loop that updates 30 to 60 times a second. Rather than respond to incoming
|
||
/// messages and tokens via the `OnMessage` virtual function, this class will
|
||
/// queue up the message internally in a thread-safe manner so that it can be
|
||
/// consumed with `PollMessage`. For example:
|
||
///
|
||
/// ::firebase::messaging::PollableListener listener;
|
||
/// ::firebase::messaging::Initialize(app, &listener);
|
||
///
|
||
/// while (true) {
|
||
/// std::string token;
|
||
/// if (listener.PollRegistrationToken(&token)) {
|
||
/// LogMessage("Received a registration token");
|
||
/// }
|
||
///
|
||
/// ::firebase::messaging::Message message;
|
||
/// while (listener.PollMessage(&message)) {
|
||
/// LogMessage("Received a new message");
|
||
/// }
|
||
///
|
||
/// // Remainder of application logic...
|
||
/// }
|
||
class PollableListener : public Listener {
|
||
public:
|
||
/// @brief The default constructor.
|
||
PollableListener();
|
||
|
||
/// @brief The required virtual destructor.
|
||
virtual ~PollableListener();
|
||
|
||
/// @brief An implementation of `OnMessage` which adds the incoming messages
|
||
/// to a queue, which can be consumed by calling `PollMessage`.
|
||
virtual void OnMessage(const Message& message);
|
||
|
||
/// @brief An implementation of `OnTokenReceived` which stores the incoming
|
||
/// token so that it can be consumed by calling `PollRegistrationToken`.
|
||
virtual void OnTokenReceived(const char* token);
|
||
|
||
/// @brief Returns the first message queued up, if any.
|
||
///
|
||
/// If one or more messages has been received, the first message in the
|
||
/// queue will be popped and used to populate the `message` argument and the
|
||
/// function will return `true`. If there are no pending messages, `false` is
|
||
/// returned. This function should be called in a loop until all messages have
|
||
/// been consumed, like so:
|
||
///
|
||
/// ::firebase::messaging::Message message;
|
||
/// while (listener.PollMessage(&message)) {
|
||
/// LogMessage("Received a new message");
|
||
/// }
|
||
///
|
||
/// @param[out] message The `Message` struct to be populated. If there were no
|
||
/// pending messages, `message` is not modified.
|
||
///
|
||
/// @return Returns `true` if there was a pending message, `false` otherwise.
|
||
bool PollMessage(Message* message);
|
||
|
||
/// @brief Returns the registration key, if a new one has been received.
|
||
///
|
||
/// When a new registration token is received, it is cached internally and can
|
||
/// be retrieved by calling `PollRegistrationToken`. The cached registration
|
||
/// token will be used to populate the `token` argument, then the cache will
|
||
/// be cleared and the function will return `true`. If there is no cached
|
||
/// registration token this function retuns `false`.
|
||
///
|
||
/// std::string token;
|
||
/// if (listener.PollRegistrationToken(&token)) {
|
||
/// LogMessage("Received a registration token");
|
||
/// }
|
||
///
|
||
/// @param[out] token A string to be populated with the new token if one has
|
||
/// been received. If there were no new token, the string is left unmodified.
|
||
///
|
||
/// @return Returns `true` if there was a new token, `false` otherwise.
|
||
bool PollRegistrationToken(std::string* token) {
|
||
bool got_token;
|
||
std::string token_received = PollRegistrationToken(&got_token);
|
||
if (got_token) {
|
||
*token = token_received;
|
||
}
|
||
return got_token;
|
||
}
|
||
|
||
private:
|
||
std::string PollRegistrationToken(bool* got_token);
|
||
|
||
// The implementation of the `PollableListener`.
|
||
PollableListenerImpl* impl_;
|
||
};
|
||
|
||
} // namespace messaging
|
||
} // namespace firebase
|
||
|
||
#endif // FIREBASE_MESSAGING_CLIENT_CPP_SRC_INCLUDE_FIREBASE_MESSAGING_H_
|