augusl/yii2-fcm-both-api

用于通过 Firebase Cloud Messaging (FCM) HTTP 服务器协议(API)发送推送通知的 Yii2 扩展。

安装: 45

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 0

分支: 13

类型:yii2-extension

0.9.6 2021-08-09 02:48 UTC

This package is auto-updated.

Last update: 2024-09-09 09:51:24 UTC


README

用于通过 Firebase Cloud Messaging (FCM) HTTP 服务器协议(API)发送推送通知的 Yii2 扩展。

Latest Stable Version Total Downloads Build Status

此扩展支持通过当前支持的 FCM API 版本发送推送通知

注意:当前不支持 XMPP 协议。

安装

安装此扩展的首选方式是通过 composer。请检查此扩展的composer.json 文件以获取其要求和依赖项。

要安装,请运行

$ php composer.phar require aksafan/yii2-fcm-both-api

或添加

"aksafan/yii2-fcm-both-api": "*"

到您的 composer.json 文件的 require 部分。

配置

为了使用此库,您必须配置应用配置中的 Fcm 类。

对于 ApiV1

return [
    //....
    'components' => [
        'fcm' => [
             'class' => 'aksafan\fcm\source\components\Fcm',
             'apiVersion' => \aksafan\fcm\source\requests\StaticRequestFactory::API_V1,
             'apiParams' => [
                 'privateKey' => '/path/to/your/file/privateKeyFile.json',
             ],
        ],
    ]
];

privateKey - 用于验证服务帐户并授权其访问 Firebase 服务。您必须 生成 一个 JSON 格式的私钥文件并使用此密钥检索一个短期的 OAuth 2.0 令牌。privateKey 可以设置为 json-file '/path/to/your/file/privateKeyFile.json' 或简单设置为 json-string '{"type":"service_account"}'

对于旧版 API

return [
    //....
    'components' => [
        'fcm' => [
             'class' => 'aksafan\fcm\source\components\Fcm',
             'apiVersion' => \aksafan\fcm\source\requests\StaticRequestFactory::LEGACY_API,
             'apiParams' => [
                 'serverKey' => 'aef',
                 'senderId' => 'fwef',
             ],
        ],
    ]
];

serverKey - 授权您的应用服务器访问 Google 服务的服务器密钥,包括通过 Firebase Cloud Messaging 旧版协议发送消息。您在创建 Firebase 项目时获得服务器密钥。您可以在 Firebase 控制台设置面板的 云消息 选项卡中查看它。

senderId - 当您创建 Firebase 项目时创建的唯一数值,可在 Firebase 控制台设置面板的 云消息 选项卡中查看。发送者 ID 用于识别每个可以向客户端应用发送消息的发送者。

还将此添加到项目根目录的 Yii.php 文件中,以便 IDE 代码自动完成。
/**
 * Class WebApplication
 * Include only Web application related components here.
 *
 * @property \aksafan\fcm\source\components\Fcm $fcm
 */
class WebApplication extends yii\web\Application
{
}
现在您可以通过
Yii::$app->fcm

基本用法

注意。 此库的主要用途是在队列中,因此我们试图在面向对象和低对象使用量之间取得平衡。

APIv1

扩展的 APIv1 部分可以发送

  1. 一个消息到特定的令牌(设备)
  2. 一个消息到一个给定的主题
  3. 一个消息到多个 主题 通过条件。

消息可以包含

  1. 两种类型的消息:通知消息数据消息(两者都是可选的)。
  2. 它们的组合
  3. 特定平台的目标平台配置
向单个令牌(设备)发送推送通知

您需要为目标设备有一个注册令牌。注册令牌是由客户端 FCM SDK 生成的一串字符串。每个 Firebase 客户端 SDK 都能生成这些注册令牌:[iOS](https://firebase.google.com/docs/cloud-messaging/ios/client#access_the_registration_token),[Android](https://firebase.google.com/docs/cloud-messaging/android/client#sample-register),[Web](https://firebase.google.com/docs/cloud-messaging/js/client#access_the_registration_token)。为了向单个令牌发送推送,您需要使用 setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token') 方法,其中 \aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN 是一个常量。

/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token')
    ->send();
向一个主题发送推送通知

基于发布/订阅模型,FCM 主题消息允许您向已选择特定主题的多个设备发送消息。您根据需要编写主题消息,FCM 负责路由并将消息可靠地传送到正确的设备。

要(取消)订阅设备到主题,请查看下方的主题管理部分。

例如,使用本地天气预报应用程序的用户可以选择“严重天气警报”主题,并接收到威胁特定地区的风暴通知。体育应用程序的用户可以订阅他们最喜欢的球队的实时比分自动更新。

关于主题需要考虑的主要事项

  • 开发者可以选择任何匹配正则表达式 [a-zA-Z0-9-_.~%]+ 的主题名称。
  • 主题消息支持每个应用程序无限的主题和订阅。
  • 主题消息最适合新闻、天气或其他公共信息等内容的传播。
  • 主题消息针对吞吐量进行了优化,而不是延迟。对于快速、安全地将消息发送到单个设备或小批量设备,请针对注册令牌,而不是主题,发送目标消息。

为了向主题发送推送,您需要使用 setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOPIC, 'your_token') 方法,其中 \aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOPIC 是一个常量。

/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOPIC, 'some-topic')
    ->send();
根据条件发送到主题的组合推送通知

条件是一个布尔表达式,指定目标主题。例如,以下条件将向订阅了 'TopicA' 且订阅了 'TopicB''TopicC' 的设备发送消息。

"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"

FCM 首先评估括号中的任何条件,然后从左到右评估表达式。在上面的表达式中,订阅了任何单个主题的用户不会收到消息。同样,未订阅 TopicA 的用户也不会收到消息。以下组合会收到消息:

  • TopicATopicB
  • TopicATopicC

为了通过条件向多个主题发送推送,您需要使用 setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOPIC_CONDITION, 'your_token') 方法,其中 \aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOPIC_CONDITION 是一个常量。

$condition = "'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)";
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOPIC_CONDITION, $condition)
    ->send();
只发送 'Data' 类型的推送通知。
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token')
    ->setData(['a' => '1', 'b' => 'test'])
    ->send();
只发送 'Notification' 类型的推送通知。
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token')
    ->setNotification('Test Title', 'Test Description')
    ->send();
同时发送 'Notification' 和 'Data' 类型的推送通知。
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token')
    ->setData(['a' => '1', 'b' => 'test'])
    ->setNotification('Test Title', 'Test Description')
    ->send();
不发送 'Notification' 和 'Data' 类型的推送通知。
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token')
    ->send();
使用特定平台配置发送推送通知。
Android 配置
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token')
    ->setAndroidConfig([
        'ttl' => '3600s',
        'priority' => 'normal',
        'notification' => [
            'title' => 'Android Title',
            'body' => 'Android Description.',
            'icon' => 'stock_ticker_update',
            'color' => '#ff0000',
        ],
    ])
    ->send();
APNs 配置
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token')
    ->setApnsConfig([
        'headers' => [
            'apns-priority' => '10',
        ],
        'payload' => [
            'aps' => [
                'alert' => [
                    'title' => 'iOS Title',
                    'body' => 'iOS Description.',
                ],
                'badge' => 42,
            ],
        ],
    ])
    ->send();
Web-push 配置
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\apiV1\MessageOptionsBuilder::TOKEN, 'your_token')
    ->setWebPushConfig([
        'notification' => [
            'title' => 'Web push Title',
            'body' => 'Web push Description.',
            'icon' => 'https://my-server/icon.png',
        ],
    ])
    ->send();
全部配置 配置
/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => 'test'])
    ->setNotification('Test Title', 'Test Description')
    ->setAndroidConfig([
        'ttl' => '3600s',
        'priority' => 'normal',
        'notification' => [
            'title' => 'Android Title',
            'body' => 'Andorid Description.',
            'icon' => 'push_icon',
            'color' => '#ff0000',
        ],
    ])
    ->setApnsConfig([
        'headers' => [
            'apns-priority' => '10',
        ],
        'payload' => [
            'aps' => [
                'alert' => [
                    'title' => 'iOS Title',
                    'body' => 'iOS Description.',
                ],
                'badge' => 42,
            ],
        ],
    ])
    ->setWebPushConfig([
        'notification' => [
            'title' => 'Web push Title',
            'body' => 'Web push Description.',
            'icon' => 'https://my-server/icon.png',
        ],
    ])
    ->send();

注意: 特定平台的配置将替换通用配置。

在上面的示例中,Android 客户端将接收此通知信息

'title' => 'Android Title',
'body' => 'Android Description.'

而不是这个

'title' => 'Test Title',
'body' => 'Test Description.'
处理响应。

在向 FCM 发送请求后,您将得到一个 \aksafan\fcm\source\responses\apiV1\TokenResponse 实例。

/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => 'test'])
    ->setNotification('Test Title', 'Test Description')
    ->send();
    
if ($result->isResultOk()) {
    echo $result->getRawMessageId();
    echo $result->getMessageId();
} else {
    $tokensToDelete = $result->getTokensToDelete();
    $errorDetails = $result->getErrorDetails();
    echo $result->getErrorStatusDescription();
}

如果结果为成功,您可以从 FCM 获取原始消息,格式为 - projects/your_project_id/messages/message_id

$result->getRawMessageId();

或者只获取消息 ID,格式为 - message_id

$result->getMessageId();

如果发生问题,您可以获取错误描述以及有关问题的信息

$result->getErrorStatusDescription();

以及如果问题是无效令牌,需要从您的数据库中删除的令牌

$result->getTokensToDelete();

以及来自 FCM 的技术信息

$result->getError();
$result->getErrorStatus();
$result->getErrorCode();
$result->getErrorMessage();
$result->getErrorDetails();
验证消息(干运行模式)。

您可以通过向 Firebase REST API 发送仅验证请求来验证消息。

/** @var \aksafan\fcm\source\responses\apiV1\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => 'test'])
    ->setNotification('Test Title', 'Test Description')
    ->validateOnly()
    ->send();
    
if ($result->isResultOk()) {
    echo $result->getRawMessageId();
} else {
    echo $result->getErrorStatusDescription();
}

如果消息无效,您将在错误描述中收到信息

$result->getErrorStatusDescription()

如果它是有效的,您将获得伪造的消息 - projects/your_project_id/messages/fake_message_id

$result->getMessageId();

旧版 API

扩展的旧版 API 部分可以发送

  1. 消息到特定的令牌(设备)
  2. 消息到多个令牌(设备)。
  3. 消息到 设备组
  4. 消息到特定的 主题
  5. 根据条件将消息发送到多个 主题

消息可以包含

  1. 两种类型的消息:通知消息数据消息(两者都是可选的)。
  2. 它们的组合
  3. 特定平台的目标平台配置

注意:旧版 HTTP 服务器协议仍然受到支持,被许多人使用,并且不会停用,但 Google 指导我们使用 HTTP v1 API。

向单个令牌(设备)发送推送通知

您需要为目标设备有一个注册令牌。注册令牌是由客户端 FCM SDK 生成的字符串。每个 Firebase 客户端 SDK 都能生成这些注册令牌:iOSAndroidWeb

为了向单个令牌发送推送通知,您需要使用 setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, 'your_token') 方法,其中 \aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN 为常量

/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => '2'])
    ->setNotification('Send push-notification to a single token (device)', 'Test description')
    ->send();
向多个令牌(设备)发送推送通知

一个请求中的最大令牌数量为 1000。为了向单个令牌发送推送通知,您需要使用 setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKENS, ['your_token_1', 'your_token_2', 'your_token_3']) 方法,其中 \aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKENS 为常量

$tokens = [
    'your_token_1',
    'your_token_2',
    'your_token_3',
];
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKENS, $tokens)
    ->setData(['a' => '1', 'b' => '2'])
    ->setNotification('Send push-notification to multiple tokens (devices)', 'Test description')
    ->send();
向一个主题发送推送通知

基于发布/订阅模型,FCM 主题消息允许您向已选择特定主题的多个设备发送消息。您根据需要编写主题消息,FCM 负责路由并将消息可靠地传送到正确的设备。

例如,使用本地天气预报应用程序的用户可以选择“严重天气警报”主题,并接收到威胁特定地区的风暴通知。体育应用程序的用户可以订阅他们最喜欢的球队的实时比分自动更新。

关于主题需要考虑的主要事项

  • 开发者可以选择任何匹配正则表达式 [a-zA-Z0-9-_.~%]+ 的主题名称。
  • 主题消息支持每个应用程序无限的主题和订阅。
  • 主题消息最适合新闻、天气或其他公共信息等内容的传播。
  • 主题消息针对吞吐量进行了优化,而不是延迟。对于快速、安全地将消息发送到单个设备或小批量设备,请针对注册令牌,而不是主题,发送目标消息。

为了向主题发送推送通知,您需要使用 setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOPIC, 'your_token') 方法,其中 \aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOPIC 为常量,并使用 createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_SENDING),其中 \aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_SENDING 为常量

/** @var \aksafan\fcm\source\responses\legacyApi\TopicResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_SENDING)
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOPIC, 'a-topic')
    ->setNotification('Test title', 'Test description')
    ->send();
根据条件发送到主题的组合推送通知

条件是一个布尔表达式,指定目标主题。例如,以下条件将向订阅了 'TopicA' 且订阅了 'TopicB''TopicC' 的设备发送消息。

"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"

FCM 首先评估括号中的任何条件,然后从左到右评估表达式。在上面的表达式中,订阅了任何单个主题的用户不会收到消息。同样,未订阅 TopicA 的用户也不会收到消息。以下组合会收到消息:

  • TopicATopicB
  • TopicATopicC

为了根据条件向多个主题发送推送,您需要使用setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOPIC_CONDITION, 'your_token')方法,并使用\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOPIC_CONDITION常量;以及使用createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_SENDING),并使用\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_SENDING常量。

$condition = "'a-topic' in topics && ('b-topic' in topics || 'b-topic' in topics)";
/** @var \aksafan\fcm\source\responses\legacyApi\TopicResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_SENDING)
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOPIC_CONDITION, $condition)
    ->setNotification('Test title', 'Test description')
    ->send();
向一组标记(设备)发送推送通知

FCM设备组允许您向已选择加入特定组的多台设备发送消息。您可以根据需要创建设备组,FCM负责可靠地将消息路由并投递到正确的设备。

为了向主题发送推送,您需要使用setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::GROUP, 'your_notification_key')方法,并使用\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::GROUP常量;以及使用createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_SENDING),并使用\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_SENDING常量。

$notificationKey = 'your_notification_key';
/** @var \aksafan\fcm\source\responses\legacyApi\GroupResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_SENDING)
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::GROUP, $notificationKey)
    ->setData(['a' => '1', 'b' => '2'])
    ->setNotification('Test title', 'Test description')
    ->send();
只发送 'Data' 类型的推送通知。
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => 'test'])
    ->send();
只发送 'Notification' 类型的推送通知。
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setNotification('Test title', 'Test Description')
    ->send();
同时发送 'Notification' 和 'Data' 类型的推送通知。
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => 'test'])
    ->setNotification('Send push-notification with both \'Notification\' and \'Data\' message type.', 'Test Description')
    ->send();
不发送 'Notification' 和 'Data' 类型的推送通知。
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = Yii::$app
    ->fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, 'your_token')
    ->send();
使用特定平台配置发送推送通知。
Android 配置
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setAndroidConfig([
        'title' => 'Android Title',
        'body' => 'Android Description.',
        'icon' => 'stock_ticker_update',
        'color' => '#ff0000',
    ])
    ->setPriority(\aksafan\fcm\source\helpers\OptionsHelper::HIGH)
    ->send();
APNs 配置
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setApnsConfig([
        'title' => 'iOS Title',
        'body' => 'iOS Description.',
        'title_loc_key' => 'iOS Title loc key.',
        'badge' => '42',
        'sound' => 'bingbong.aiff',
    ])
    ->send();
Web-push 配置
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setWebPushConfig([
        'title' => 'Web push Title',
        'body' => 'Web push Description.',
        'icon' => 'https://my-server/icon.png',
        'click_action' => 'click-action',
    ])
    ->send();
所有配置汇总 这里

您可以使用这些方法设置额外的配置

    ->setCollapseKey(')
    ->setPriority()
    ->setContentAvailable()
    ->setMutableContent()
    ->setTimeToLive()
    ->setRestrictedPackageName()
    ->validateOnly()

所有配置汇总可以是

/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => '2'])
    ->setNotification('Test title', 'Test description')
    ->setAndroidConfig([
        'title' => 'Android Title',
        'body' => 'Android Description.',
        'icon' => 'stock_ticker_update',
        'color' => '#ff0000',
    ])
    ->setApnsConfig([
        'title' => 'iOS Title',
        'body' => 'iOS Description.',
        'title_loc_key' => 'iOS Title loc key.',
        'badge' => '42',
        'sound' => 'bingbong.aiff',
    ])
    ->setWebPushConfig([
        'title' => 'Web push Title',
        'body' => 'Web push Description.',
        'icon' => 'https://my-server/icon.png',
        'click_action' => 'click-action',
    ])
    ->setCollapseKey('collapse_key')
    ->setPriority(\aksafan\fcm\source\helpers\OptionsHelper::NORMAL)
    ->setContentAvailable(true)
    ->setMutableContent(false)
    ->setTimeToLive(300)
    ->setRestrictedPackageName('restricted_package_mame')
    ->validateOnly(false)
    ->send();

注意:请注意,平台特定配置将替换通用配置,并且会依次替换其他平台的配置(在旧版API版本中缺少),依次类推:

    GeneralNotificationConfig
         ->
    AndroidConfig
         ->
    ApnsConfig
         ->
    WebPushConfig

在上面的示例中,任何客户端都将收到这些通知信息

'title' => 'Web push Title',
'body' => 'Web push Description.',
'icon' => 'https://my-server/icon.png',
'color' => '#ff0000',
'title_loc_key' => 'iOS Title loc key.',
'badge' => '42',
'sound' => 'bingbong.aiff',
'click_action' => 'click-action',

而不是所有提到的。

处理响应。

在向FCM发送请求后,您将获得以下实例之一

  • \aksafan\fcm\source\responses\legacyApi\TokenResponse
  • \aksafan\fcm\source\responses\legacyApi\TopicResponse
  • \aksafan\fcm\source\responses\legacyApi\GroupResponse
用于向单个(多个)标记发送推送消息
/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => '2'])
    ->setNotification('Test title', 'Test description')
    ->send();
    
if ($result->isResultOk()) {
    echo 'MessageId '.$result->getMessageId();
    echo 'NumberSuccess '.$result->getNumberSuccess();
    echo 'NumberFailure '.$result->getNumberFailure();
    echo 'NumberModification '.$result->getNumberModification();
} else {
    echo 'numberSuccess '.$result->getNumberSuccess();
    echo 'numberFailure '.$result->getNumberFailure();
    echo 'numberModification '.$result->getNumberModification();
    echo 'TokensToDelete '.$result->getTokensToDelete();
    echo 'TokensToModify '.$result->getTokensToModify();
    echo 'TokensToRetry '.$result->getTokensToRetry();
    echo 'RetryAfter '.$result->getRetryAfter();
    echo 'TokensWithError '.$result->getTokensWithError();
    echo 'ErrorStatusDescription '.$result->getErrorStatusDescription();
}

如果结果正常,您可以获取消息ID,格式为message_id

$result->getMessageId();

您可以看到成功发送的消息数量

$result->getNumberSuccess();

失败的尝试次数

$result->getNumberFailure();

需要修改其标记的设备数量

$result->getNumberModification();

如果发生问题,您可以获取错误描述以及有关问题的信息

$result->getErrorStatusDescription();

有关旧版API的常见错误及其处理方法的列表 这里

还应从您的数据库中删除这些无效的标记

$result->getTokensToDelete();

需要在您的存储中更改这些标记 - ['oldToken' => 'newToken']

$result->getTokensToModify();

需要在发送中重新发送这些标记。您应使用指数退避来重试发送

$result->getTokensToRetry();

如果响应头中包含,则重试后需要的时间

$result->getRetryAfter();

存在错误的标记。您应检查这些标记以删除损坏的标记

$result->getTokensWithError();
用于向主题或按条件向主题发送推送消息
/** @var \aksafan\fcm\source\responses\legacyApi\TopicResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_SENDING)
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOPIC, 'a-topic')
    ->setNotification('Test title', 'Test description')
    ->send();
    
if ($result->isResultOk()) {
    echo 'MessageId '.$result->getMessageId();
} else {
    echo 'ErrorMessage '.$result->getErrorMessage();
    echo 'ErrorStatusDescription '.$result->getErrorStatusDescription();
}

如果结果正常,您可以获取消息ID,格式为message_id

$result->getMessageId();

如果发生问题,您可以获取错误描述以及有关问题的信息

$result->getErrorStatusDescription();

错误消息

$result->getErrorMessage();
用于向设备组发送推送消息
$notificationKey = 'your_notification_key';
/** @var \aksafan\fcm\source\responses\legacyApi\GroupResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_SENDING)
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::GROUP, $notificationKey)
    ->setData(['a' => '1', 'b' => '2'])
    ->setNotification('Test title', 'Test description')
    ->send();
    
if ($result->isResultOk()) {
    echo 'numberSuccess ' . $result->getNumberSuccess();
    echo 'numberFailure ' . $result->getNumberFailure();
} else {
    echo 'numberSuccess ' . $result->getNumberSuccess();
    echo 'numberFailure ' . $result->getNumberFailure();
    echo 'tokensFailed ' . print_r($tokensFailed = $result->getTokensFailed());
    echo 'ErrorStatusDescription '.$result->getErrorStatusDescription();
}

如果结果正常,您可以获取成功发送消息的标记数量

$result->getNumberSuccess();

未成功发送消息的标记数量

$result->getNumberFailure();

如果服务器尝试向没有成员的设备组发送消息,则响应将为成功0次和失败0次。

如果发生问题,您可以获取错误描述以及有关问题的信息

$result->getErrorStatusDescription();

失败标记的数组

$result->getTokensFailed();

当消息无法投递到一个或多个与notification_key关联的注册标记时,应用服务器应在重试之间使用退避策略。

验证消息(干运行模式)。

您可以通过向 Firebase REST API 发送仅验证请求来验证消息。

/** @var \aksafan\fcm\source\responses\legacyApi\TokenResponse $result */
$result = $fcm
    ->createRequest()
    ->setTarget(\aksafan\fcm\source\builders\legacyApi\MessageOptionsBuilder::TOKEN, $token)
    ->setData(['a' => '1', 'b' => 'test'])
    ->setNotification('Validating messages', 'Test Description')
    ->validateOnly()
    ->send();
    
if ($result->isResultOk()) {
    echo $result->getMessageId();
} else {
    echo $result->getErrorStatusDescription();
}

如果消息无效,您将在错误描述中收到信息

$result->getErrorStatusDescription()

如果是有效的,您将得到fake_message - -1

$result->getMessageId();
设备组 管理

这里有三个主要定义

  • groupName - 是一个名称或标识符(例如,它可以是一个用户名),在给定的组中是唯一的;
  • notificationKey - 通过将特定的组(通常是一个用户)映射到组的所有关联的注册令牌来标识设备组;
  • tokens - 一个包含您想要添加到组中的每个设备注册令牌的数组。

groupNamenotificationKey 对注册令牌组是唯一的。如果您有多个针对同一发送者ID的客户应用,则groupName对每个客户应用必须是唯一的。这确保了消息只会发送到目标应用。

可选地,Android客户应用可以从客户端管理设备组。

创建组

要创建设备组,您需要使用带有组名称和设备注册令牌列表的 createGroup(string $groupName, array $tokens) 方法。同时,使用 \aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_MANAGEMENT 参数创建请求。

$groupName = 'test-group';
$tokens = [
    'your_token_1',
    'your_token_2',
    'your_token_3',
    'your_token_4',
    'your_token_5',
];
/** @var \aksafan\fcm\source\responses\legacyApi\GroupManagementResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_MANAGEMENT)
    ->createGroup($groupName, $tokens)
    ->send();
if ($result->isResultOk()) {
    echo 'NotificationKey '.$notificationKey = $result->getNotificationKey();
} else {
    echo 'getErrorStatusDescription '. $result->getErrorStatusDescription();
}

向 FCM 发送请求后,您将获得一个 \aksafan\fcm\source\responses\legacyApi\GroupManagementResponse 实例。

FCM 返回一个代表设备组的新的 notificationKey。保存它和相应的 groupName 以供后续操作使用。

如果有错误,您将在错误描述中收到信息

$result->getErrorStatusDescription()

注意。 您可以在单个请求中将最多 1,000 台设备添加到组中。如果您提供了一个包含超过 1,000 个注册令牌的数组,则请求将因 InvalidArgumentException 而失败。

从组中检索 notificationKey

如果您需要检索现有的 notificationKey,则需要使用带有组名称的 getNotificationKey(string $groupName) 方法。同时,使用 \aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_MANAGEMENT 参数创建请求。

$groupName = 'test-group';
/** @var \aksafan\fcm\source\responses\legacyApi\GroupManagementResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_MANAGEMENT)
    ->getNotificationKey($groupName)
    ->sendGET();
if ($result->isResultOk()) {
    echo 'NotificationKey '.$notificationKey = $result->getNotificationKey();
    echo '<br>';
} else {
    echo 'getErrorStatusDescription '. $result->getErrorStatusDescription();
    echo '<br>';
}

向 FCM 发送请求后,您将获得一个 \aksafan\fcm\source\responses\legacyApi\GroupManagementResponse 实例。

FCM 返回代表设备组的 notificationKey

如果有错误,您将在错误描述中收到信息

$result->getErrorStatusDescription()

注意:在添加/删除注册令牌时,notification_key_name 不是必需的,但包括它可以保护您免受意外使用不正确的 notification_key 的影响。为了安全起见,当前扩展使您始终使用 groupName

向组添加令牌

您可以通过传递注册令牌到 addToGroup(string $groupName, string $notificationKey, array $tokens) 方法并将 \aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_MANAGEMENT 参数创建请求来向设备组添加令牌。

$groupName = 'test-group';
$tokens = [
    'your_token_6',
    'your_token_7',
    'your_token_8',
    'your_token_9',
    'your_token_10',
];
/** @var \aksafan\fcm\source\responses\legacyApi\GroupManagementResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_MANAGEMENT)
    ->addToGroup($groupName, $notificationKey, $tokens)
    ->send();
if ($result->isResultOk()) {
    echo 'NotificationKey '.$result->getNotificationKey();
} else {
    echo 'getErrorStatusDescription '. $result->getErrorStatusDescription();
}

向 FCM 发送请求后,您将获得一个 \aksafan\fcm\source\responses\legacyApi\GroupManagementResponse 实例。

FCM 返回一个代表设备组的新 notificationKey

如果有错误,您将在错误描述中收到信息

$result->getErrorStatusDescription()
从组中删除令牌

您可以通过传递注册令牌到 removeFromGroup(string $groupName, string $notificationKey, array $tokens) 方法并将 \aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_MANAGEMENT 参数创建请求来从设备组中删除令牌。

$groupName = 'test-group';
$tokens = [
    'your_token_6',
    'your_token_7',
];
/** @var \aksafan\fcm\source\responses\legacyApi\GroupManagementResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_GROUP_MANAGEMENT)
    ->removeFromGroup($groupName, $notificationKey, $tokens)
    ->send();
if ($result->isResultOk()) {
    echo 'NotificationKey '.$result->getNotificationKey();
    echo '<br>';
} else {
    echo 'getErrorStatusDescription '. $result->getErrorStatusDescription();
    echo '<br>';
}

向 FCM 发送请求后,您将获得一个 \aksafan\fcm\source\responses\legacyApi\GroupManagementResponse 实例。

FCM 返回一个代表设备组的新 notificationKey

如果有错误,您将在错误描述中收到信息

$result->getErrorStatusDescription()

如果您从设备组中删除了所有现有的注册令牌,FCM 将删除该设备组。

主题 管理

注意:您可以通过两种 API 版本(选择您喜欢的并 配置 它)订阅(取消订阅)主题。

订阅主题

您可以通过将注册令牌传递给 subscribeToTopic(string $topic, array $tokens) 方法并创建带有 \aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_MANAGEMENT 参数的请求来将一个或多个设备订阅到主题。

$topic = 'test-topic';
$tokens = [
    'your_token_1',
    'your_token_2',
    'your_token_3',
    'your_token_4',
    'your_token_5',
];
/** @var \aksafan\fcm\source\responses\TopicSubscribeResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_MANAGEMENT)
    ->subscribeToTopic($topic, $tokens)
    ->send();

注意。 您可以在单个请求中将最多 1,000 台设备订阅到主题。如果您提供了一个包含超过 1,000 个注册令牌的数组,则请求将因 InvalidArgumentException 而失败。

向 FCM 发送请求后,您将获得一个 \aksafan\fcm\source\responses\TopicSubscribeResponse 实例。现在您可以使用 错误 捕获令牌。

$tokensWithError = $result->getTopicTokensWithError();

这是一个格式中与对应错误匹配的令牌数组

$tokensWithError = [
    [
        'token' => 'your_token_2',
        'error' => 'INVALID_ARGUMENT',
    ],
    [
        'token' => 'your_token_4',
        'error' => 'INVALID_ARGUMENT',
    ],
    [
        'token' => 'your_token_5',
        'error' => 'INVALID_ARGUMENT',
    ],
];

所有其他令牌都正确订阅。

取消订阅 主题

您可以通过传递注册令牌到 unsubscribeFromTopic(string $topic, array $tokens) 方法,并使用 \aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_MANAGEMENT 参数创建请求,来取消一个或多个设备对一个主题的订阅

$topic = 'test-topic';
$tokens = [
    'your_token_1',
    'your_token_2',
    'your_token_3',
    'your_token_4',
    'your_token_5',
];
/** @var \aksafan\fcm\source\responses\TopicSubscribeResponse $result */
$result = $fcm
    ->createRequest(\aksafan\fcm\source\builders\StaticBuilderFactory::FOR_TOPIC_MANAGEMENT)
    ->unsubscribeFromTopic($topic, $tokens)
    ->send();

注意。 您可以在单个请求中取消最多 1,000 个设备的订阅。如果您提供一个包含超过 1,000 个注册令牌的数组,请求将因消息/无效参数错误而失败。

向 FCM 发送请求后,您将获得一个 \aksafan\fcm\source\responses\TopicSubscribeResponse 实例。现在您可以使用 错误 捕获令牌。

$tokensWithError = $result->getTopicTokensWithError();

这是一个格式中与对应错误匹配的令牌数组

$tokensWithError = [
    [
        'token' => 'your_token_2',
        'error' => 'INVALID_ARGUMENT',
    ],
    [
        'token' => 'your_token_4',
        'error' => 'INVALID_ARGUMENT',
    ],
    [
        'token' => 'your_token_5',
        'error' => 'INVALID_ARGUMENT',
    ],
];

所有其他令牌都正确取消订阅。

日志记录

此扩展通过 \Yii::error() 使用原生 Yii2 错误记录器。可以在此处找到使用的错误类别列表 aksafan\fcm\source\helpers\ErrorsHelper::LOGS_ERRORS

许可

版权所有 2018 年 Anton Khainak。

MIT 许可下可用。

完整的 FCM 文档可以在此处找到 Firebase Cloud Messaging