10 个版本 (6 个稳定版)
3.0.0 | 2024 年 1 月 13 日 |
---|---|
2.0.3 | 2023 年 12 月 23 日 |
2.0.2 | 2023 年 11 月 23 日 |
2.0.1 | 2023 年 3 月 12 日 |
0.1.1 | 2023 年 2 月 26 日 |
#653 在 网页开发 中
每月 下载 38 次
36KB
607 行
概述
此 crate 将监听来自 Firebase Cloud Messaging (FCM) 的推送消息。
重要
对于 3.0.0 版本之前的版本,注册将在 2024 年 6 月 20 日停止工作,因为 Google 将关闭一个它所调用的 API。您需要在此时间之前升级,以便库继续工作。
先决条件
- Firebase App ID - Firebase 控制台 -> 项目设置 -> 通用 -> 您的应用 -> App ID
将其制作为一个 Android 应用,因为我们将会调用 Android 设备检查 API。
- Firebase 项目 ID - Firebase 控制台 -> 项目设置 -> 通用 -> 项目 ID
- Firebase API 密钥 - Google Cloud 控制台 -> API 和服务 -> 凭据 -> API 密钥
API 密钥所需的权限:Firebase Cloud Messaging API、云消息、Firebase 安装 API、FCM 注册 API。
- VAPID 密钥 - Firebase 控制台 -> 项目设置 -> 云消息 -> 网页配置 -> 网页推送证书
您需要的是“密钥对”列下列出的公钥。
使用方法
use fcm_push_listener::FcmPushListener;
let firebase_app_id = "1:1001234567890:android:2665128ba997ffab830a24";
let firebase_project_id = "myapp-1234567890123";
let firebase_api_key = "aBcDeFgHiJkLmNoPqRsTu01234_aBcD0123456789";
let vapid_key = "BClpBSn3aL7aZ2JZxWB0RrdBqw-5-A7xLoeoxBWdcjxnby4MFvTG8nIa1KHmSY2-cmCAySR4PoCcOZtW18aXNw1";
let registration = fcm_push_listener::register(
firebase_app_id,
firebase_project_id,
firebase_api_key,
vapid_key).await?;
// Send registration.fcm_token to the server to allow it to send push messages to you.
let mut listener = FcmPushListener::create(
registration,
|message: FcmMessage| {
println!("Message JSON: {}", message.payload_json);
println!("Persistent ID: {:?}", message.persistent_id);
},
|err| { eprintln!("{:?}", err) },
vec!["0:1677356129944104%7031b2e6f9fd7ecd".to_owned()]);
listener.connect().await?;
您需要保存接收到的消息的持久 ID,然后在下一次调用 connect()
时传入。这样,您就确认了消息的接收,并避免了再次触发它们。
注册需要解密推送消息的秘密;将其存储在安全位置,并在下一次调用 connect()
时重复使用。 Registration
被标记为 Serialize
和 Deserialize
,因此您可以直接使用它。
示例 payload_json
{
"data": {
"myProp": "myValue"
},
"from": "1001234567890",
"priority": "normal",
"fcmMessageId": "2cca9428-b164-401c-be3b-e01d8bce6dcd"
}
data
属性包含推送的对象。您可以使用您选择的任何库进行 JSON 解析。
取消
由于 connect()
返回一个 Future
并且运行时间较长,我建议从任务中创建并启动监听器。然后,您可以取消/中止任务以停止推送监听器,并且您的应用程序可以自由地在主线程上执行其他活动。
例如,您可以设置一个服务来管理推送监听器
struct PushService {
task: Option<JoinHandle<()>>,
some_state: String,
}
impl PushService {
pub fn new() -> Self {
PushService {
task: None,
some_state: "abc".to_owned()
}
}
pub fn start(&mut self) {
let some_state = self.some_state.clone();
self.task = Some(tokio::task::spawn(async move {
let registration = /* Get registration from storage or call fcm_push_listener::register() */;
let mut listener = FcmPushListener::create(
registration,
|message: FcmMessage| {
println!("Captured state: {}", some_state);
println!("Message JSON: {}", message.payload_json);
println!("Persistent ID: {:?}", message.persistent_id);
},
vec![]);
let result = listener.connect().await;
if let Err(err) = result {
eprintln!("{:?}", err);
}
}));
}
pub fn stop(&mut self) {
if let Some(task) = &self.task {
task.abort();
self.task = None;
}
}
}
然后保留一个PushService实例,并在需要取消时调用stop()
。
实现
依赖项
tokio
用于异步/TCP。rustls
/tokio-rustls
用于推送监听器的TLS连接。reqwest
用于HTTP调用。prost
用于protobuf。ece
用于创建Web推送密钥对和解密消息。
注册()
- 调用 https://android.clients.google.com/checkin 获取Android ID。
- 调用 https://android.clients.google.com/c2dm/register3 在GCM中进行注册。给您一个GCM令牌和一个安全令牌。(其他库有时将GCM令牌称为ACG令牌)
- 调用 https://firebaseinstallations.googleapis.com/v1/projects/{project_id}/installations 获取Firebase安装令牌。
- 使用
ece
的旧版aesgcm
模式创建一个加密密钥对。 - 调用 https://fcmregistrations.googleapis.com/v1/projects/{project_id}/registrations 进行最终的FCM注册并获取FCM令牌。
FcmPushListener.连接()
- 进行另一个checkin调用以保持我们的“设备”最新。
- 与
mtalk.google.com:5228
建立TLS/TCP连接,并发送通过protobuf编码的信息,使用生成的设备ID和我们看到的持久ID列表进行登录。 - 保持套接字连接打开以监听推送消息。
消息
当推送消息到达时,它使用protobuf解析出有效载荷和元数据,然后使用注册中存储的私钥和认证密钥解密有效载荷并将其解码为UTF-8字符串。然后它调用提供的闭包,传递JSON有效载荷和持久ID。
重连
如果连接在成功建立后被关闭,它将自动尝试重新打开连接。
致谢
这是基于Matthieu Lemoine的NPM包 push-receiver。他的逆向工程努力非常英勇!
构建设置
- 前往 https://github.com/protocolbuffers/protobuf/releases ,找到最新稳定版,然后从protoc-{version}-{platform}.zip中提取protoc.exe并将其放入路径。
- 设置OpenSSL。对于Windows,从 https://slproweb.com/products/Win32OpenSSL.html 安装并设置环境变量
OPENSSL_DIR
为C:\Program Files\OpenSSL-Win64
(或您安装它的位置)
依赖项
~16–30MB
~563K SLoC