aksafan/yii2-fcm-both-api

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

0.10.0 2020-09-16 12:25 UTC

This package is auto-updated.

Last update: 2024-09-16 21:22:12 UTC


README

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

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
为了同时使用 HTTP v1 和旧版 API,您需要单独注册它们
return [
    //....
    'components' => [
        'fcmApiV1' => [
            'class' => 'aksafan\fcm\source\components\Fcm',
            'apiVersion' => \aksafan\fcm\source\requests\StaticRequestFactory::API_V1,
            'apiParams' => [
                'privateKey' => '/path/to/your/file/privateKeyFile.json',
            ],
        ],
        'fcmLegacyApi' => [
            'class' => 'aksafan\fcm\source\components\Fcm',
            'apiVersion' => \aksafan\fcm\source\requests\StaticRequestFactory::LEGACY_API,
            'apiParams' => [
                'serverKey' => 'aef',
                'senderId' => 'fwef',
            ],
        ],
    ]
];

现在,当需要 APIV1 时,您可以使用 Yii::$app->fcmApiV1,对于旧版 API,请使用 Yii::$app->fcmLegacyApi

基本用法

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

APIv1

扩展的 APIv1 部分可以发送

  1. 一条消息到特定的 令牌(设备)
  2. 一条消息到给定的 主题
  3. 根据条件向多个 主题 发送消息。

消息可以包含

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

您需要为目标设备拥有注册令牌。注册令牌是由客户端 FCM SDK 生成的字符串。每个 Firebase 客户端 SDK 都能生成这些注册令牌:iOSAndroidWeb。为了向单个令牌发送推送通知,您需要使用 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();

或者仅以格式为 - message_id 的消息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();
}

如果结果是 OK,您可以在格式 - message_id 中获取消息 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();
}

如果结果是 OK,您可以在格式 - message_id 中获取消息 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();
}

如果结果是 OK,您可以得到成功发送消息的令牌数量

$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()

注意:对于添加/删除注册令牌,通知键名称不是必需的,但包括它可以防止意外使用错误的通知键。为了安全起见,当前扩展使您始终使用 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