React Native推送通知
建筑学
通知类型
React Native 库
iOS 设置
Android 设置
React Native 实现
测试 iOS 推送通知
测试安卓推送通知
概括
你想在用 React Native 编写的全新移动应用中启用推送通知功能。但如果你是移动开发新手,对推送通知的工作原理一无所知,你可能会感到困惑(就像我第一次那样)。推送通知到底难在哪里呢?
- 每个平台(Android、iOS)的实现方式都不同。
- React Native 的实现方式因平台而异,React Native 推送通知库也可能存在差异。
- 其中涉及到一些后端/服务器端技术。
- 从用户角度来看,根据应用程序的状态(打开、后台运行、关闭)的不同,行为也会有所不同。
- 各种类型的通知(本地/远程、前台/后台等)。
首先,我们来看看推送通知的一般细节,然后我将讨论 React Native 库的选择,并向您展示如何在每个平台上设置推送通知和 React Native 通知库。
建筑学
APNs(Apple 推送通知服务)和FCM(Firebase 云消息传递)分别是 Apple 为 iOS 和 Google 为 Android 提供的云服务。作为开发者,要使用这些服务,您需要将应用注册到 APNs 或 FCM(稍后我会解释如何操作)。注册完成后,您将获得 iOS 的证书和 FCM 的服务器 API 密钥,需要将它们保存到您的通知提供商中。通知提供商可以是 AWS SNS 等。您也可以使用 FCM,或者自行构建 FCM,或者将其集成到您的后端系统中。
APNs 和 FCM 服务的目标是让您无需知道用户设备的 IP 地址即可向用户发送通知。您只需在应用中添加一些代码,将用户设备注册到 APNs 或 FCM 并返回一个设备令牌。然后,您可以通过通知提供程序从后端系统向 APNs 或 FCM 发送针对给定设备令牌的通知消息,剩下的工作——将消息送达用户设备——就由它们负责了。
通知类型
前景与背景
- 前台通知是指当应用程序打开并运行时,用户收到的通知。
- 后台通知是指应用在后台运行时或应用关闭时收到的通知。
根据应用程序在用户设备上的状态,处理通知的行为和 API 会有所不同,您必须为此做好准备。
远程与本地
本地通知是指从应用内部发起,并按指定时间或重复发送到系统通知中心的通知。此类通知并非由服务器发送。相反,远程通知则是由服务器发送的。本文将主要讨论远程通知。
React Native 库
目前为止,我已经尝试过两个库:
我一开始使用的是 zo0r/react-native-push-notification,但是我在 iOS 上接收后台通知时遇到了问题,所以我改用了 wix/react-native-notifications。
运行以下命令安装库:
- 纱线:
yarn add react-native-notifications或 - NPM
npm install —save react-native-notifications:。
现在,您可以根据需要查看 iOS 或 Android 的设置部分。无论如何,在进入任何平台的“测试”部分之前,您都需要先查看React Native 实现部分。
iOS 设置
加入苹果开发者计划
如果你想发送远程通知,哪怕只是为了测试,也必须加入苹果开发者计划。该计划每年收费 100 美元,但如果你想在 App Store 上发布应用,无论如何都需要加入。
启用推送通知
在 Xcode 中打开你的项目。我使用的是 RN > 0.60 版本,所以我打开…… PushNotificationsWixDemo.xcworkspace。前往 Xcode 项目设置 -> 功能,然后启用推送通知(参见“向目标添加功能”)。要看到“功能”菜单中的此选项,你需要使用已注册 Apple 开发者计划的 Apple ID 登录 Xcode,正如我之前提到的。“高级应用功能”会显示特定功能所需的开发者帐户类型。
创建证书
您需要创建 TLS 证书才能与 APNs 通信。您可以在Apple 开发者帐户页面的“证书、标识符和配置文件”部分进行此操作。
开始之前,您需要创建一个证书签名请求 (CSR )(请务必填写“通用名称”字段,否则由此 CSR 创建的证书将无法正常工作)。创建完成后,例如,按照“使用 TLS 证书与 APNs 通信”CertificateSigningRequest.certSigningRequest中的说明继续创建证书。当系统询问证书类型时,只需选择“开发 SSL 证书”,这足以满足您在项目中测试推送通知的需求。对于通过 App Store 分发的正式版应用,甚至通过 TestFlight 进行 Beta 测试的应用,您都需要创建“生产 SSL 证书”。
在此过程中,您将创建、下载cer文件并将其添加到您的钥匙串中。然后,您将导出p12文件,我们稍后将使用该文件来测试推送通知。
注意:在撰写本文时,我发现还有另一种选择:使用身份验证令牌与 APNs 通信,但我还没有尝试过。
其他有用资源:
React Native 设置
继续执行 React Native 通知入门指南中的其他步骤 ·与 iOS 相关的 React Native 通知:
pod install —project-directory=ios/- 更新
AppDelegate.m
Android 设置
正如我之前提到的,Android 使用 FCM 进行推送通知。可以说它更简单易用。你只需要一个 Google 帐户登录 Firebase 控制台,然后创建一个 Android 项目即可。不过有一点可能会让人有点困惑。你也可以为其他平台(例如 iOS、Web、C++ 或 Unity)设置和使用 FCM,但这仅仅意味着 FCM 可以像我们图中的通知提供程序一样工作。它并不能替代 APNs 服务,而且你仍然需要按照上面描述的方式进行 iOS 设置。
附注:Google 已于 2018 年 4 月 10 日弃用 GCM,并于 2019 年 4 月 11 日移除了 GCM 服务器和客户端 API。如果您之前使用过 GCM,则需要将 GCM 应用迁移到 Firebase 云消息传递。这也是为什么您有时会在依赖项或消息负载属性中看到 GCM 的原因。
创建 Firebase 项目
如果您想向 Android 发送推送通知,您需要在 Firebase 控制台中创建一个项目,并将您的应用注册到那里(如“将 Firebase 添加到您的 Android 项目 | Firebase步骤 1、2 和 3”中所述)。
-
步骤 1:创建 Firebase 项目:
- 添加项目
- 项目名称:推送通知-wix-demo
- 关闭“为此项目启用 Google Analytics(分析)”
-
步骤 2:在 Firebase 中注册您的应用:
android/app/build.gradleAndroid 包名:com.pushnotificationswixdemo(您可以在文件 android -> defaultConfig -> applicationId中找到它)- 应用昵称(可选):推送通知 Wix 演示
- 注册应用
-
步骤 3:添加 Firebase 配置文件:
- 下载
google-services.json并放入PROJECT_DIR/android/app/文件夹。 - 更新
PROJECT_DIR/android/build.gradle和文件。请注意,Firebase 控制台和Android 安装PROJECT_DIR/android/app/build.gradle中定义的特定版本可能存在差异。 · React Native 通知。我通常会尝试根据 Firebase 控制台的当前建议设置 Gradle 文件,如果与 React Native 通知库不兼容,我会降级版本。
- 下载
React Native 设置
继续执行Android 安装的其他步骤 · React Native 通知:
- 将库添加到您的应用程序类(例如 MainApplication.java)中。
- 在 React Native 中链接通知
PROJECT_DIR/android/settings.gradle
现在应该一切都设置好了。打开 Android Studio,尝试构建你的应用,检查依赖项是否正确。
Android客户端底层设置
关于如何在 Android 上设置 Firebase 云消息传递客户端应用,您可以参考这篇文章:Firebase和FirebaseMessagingService | Google APIs for Android | Google Developers。不过,wix/react-native-notifications这个库已经帮您处理了很多工作,您无需担心。我在这里只是提供一些参考信息。我觉得了解它的底层原理很有意思。
React Native 实现
创建PushNotificationsManager.js包含以下内容的文件,并将其添加到您的项目中:
import React from 'react'
import { Platform, View } from 'react-native'
import { Notifications } from 'react-native-notifications'
export default class PushNotificationManager extends React.Component {
componentDidMount() {
this.registerDevice()
this.registerNotificationEvents()
}
registerDevice = () => {
Notifications.events().registerRemoteNotificationsRegistered(event => {
// TODO: Send the token to my server so it could send back push notifications...
console.log('Device Token Received', event.deviceToken)
})
Notifications.events().registerRemoteNotificationsRegistrationFailed(event => {
console.error(event)
})
Notifications.registerRemoteNotifications()
}
registerNotificationEvents = () => {
Notifications.events().registerNotificationReceivedForeground((notification, completion) => {
console.log('Notification Received - Foreground', notification)
// Calling completion on iOS with `alert: true` will present the native iOS inApp notification.
completion({ alert: false, sound: false, badge: false })
})
Notifications.events().registerNotificationOpened((notification, completion) => {
console.log('Notification opened by device user', notification)
console.log(`Notification opened with an action identifier: ${notification.identifier}`)
completion()
})
Notifications.events().registerNotificationReceivedBackground((notification, completion) => {
console.log('Notification Received - Background', notification)
// Calling completion on iOS with `alert: true` will present the native iOS inApp notification.
completion({ alert: true, sound: true, badge: false })
})
Notifications.getInitialNotification()
.then(notification => {
console.log('Initial notification was:', notification || 'N/A')
})
.catch(err => console.error('getInitialNotifiation() failed', err))
}
render() {
const { children } = this.props
return <View style={{ flex: 1 }}>{children}</View>
}
}
像这样添加PushNotificationManager到文件中:App.js
import React from 'react'
import { View } from 'react-native'
import { Provider } from 'react-redux'
import PushNotificationManager from './pushNotifications'
import { RootScreen } from './router'
const App = () => {
return (
<>
<Provider store={store}>
<PushNotificationManager>
<View style={{ flex: 1 }}>
<RootScreen />
</View>
</PushNotificationManager>
</Provider>
</>
)
}
export default App
测试 iOS 推送通知
要在 iOS 上测试推送通知,您需要:
- 启动应用:目前无法通过在模拟器中运行应用来测试远程推送通知,因此您必须从 Xcode 启动应用并在连接的设备上运行。未来版本的 Xcode 将会改进这一点(请参阅如何向 iOS 模拟器发送推送通知)。
- 设备令牌:在本演示项目中,我们只是将其记录到浏览器控制台的
registerDevice方法中,您可以直接从那里复制。在实际应用中,您需要将令牌发送给通知提供商,然后从那里发送通知。 - 获取 TLS 证书:我们已在本文的 iOS 设置 -> 创建证书部分创建了此类证书。
您可以通过直接向 APNs 发送 HTTP 请求来测试推送通知curl。但首先,我们需要.pem从我们的.p12数据源生成一个通知,并将其随该请求一起发送。
通过命令.pem行从.p12证书文件创建证书:openssl
openssl pkcs12 -nodes -clcerts -in Certificates.p12 -out Certificates.pem
如果您对这些文件和文件扩展名的含义感到困惑,请尝试查看证书 - PEM、CER、CRT、P12 - 它们究竟是什么? - 信息安全 Stack Exchange。
之后,您可以使用以下命令发送 HTTP 请求(只需将abcd`<password>` 替换为您.pem在上一步中为证书设置的密码):
curl -v \
-d '{"aps":{"alert": {"title": "Game Request", "body": "Bob wants to play poker"},"sound":"default"}, "data": "some custom data"}' \
-H "apns-topic:PROJECT_BUNDLE_IDENTIFIER" \
-H "apns-expiration: 1" \
-H "apns-priority: 10" \
--http2 \
--cert CERTIFICATE_FILE_PATH:CERTIFICATE_PASS \
https://api.development.push.apple.com/3/device/DEVICE_TOKEN
其他有用资源:
测试安卓推送通知
要在 Android 上测试推送通知,您需要:
- 启动应用程序:您可以使用模拟器或连接的设备。
- 获取设备令牌:在本演示项目中,我们只是在
registerDevice方法中将其记录到浏览器控制台,您可以直接从那里复制。在实际应用中,您需要将令牌发送给通知提供商,然后从那里发送通知。 - 获取服务器密钥:您可以在项目设置 -> 云消息传递 -> 服务器密钥中找到它。
首先,您可以尝试在Firebase 控制台中进入您的项目。依次点击“云消息传递”->“通知”选项卡->“新建通知”。但这种方法存在一个问题:它不适用于初始通知。初始通知是一种特殊的后台通知,当您关闭应用并通过点击通知中心中的通知重新打开应用时,就会触发此通知。原因是 Android 区分两种类型的推送通知消息:
- 通知消息
- 数据消息
主要区别在于消息有效负载是否包含notification`data`data属性。要发送可作为初始通知处理的通知,需要data在有效负载中添加 `data` 属性,但我没有找到如何通过 Firebase 控制台发送数据消息的方法。您可以在以下链接中找到更多详细信息:
- 关于 FCM 消息 | Firebase
- 在 Android 应用中接收消息 | Firebase
- Android - 如何在 Firebase 中处理应用在后台运行时的通知 - Stack Overflow
- Android - 当应用在后台运行时,Firebase onMessageReceived 未被调用 - Stack Overflow
希望我们能使用传统的纯 HTTP 请求,curl例如通过 Postman(例如,使用 Postman 测试 FCM 通知! - Android School - Mediumcurl )。以下是我使用的命令:
curl -X POST \
https://fcm.googleapis.com/fcm/send \
-H 'Authorization: key=SERVER_KEY' \
-H 'Content-Type: application/json' \
-H 'Host: fcm.googleapis.com' \
-d '{
"to" : "DEVICE_TOKEN",
"data" : {
"body" : "Body of Your Notification in Data",
"title": "Title of Your Notification in Title",
"key_1" : "Value 1",
"key_2" : "Value 1"
}
}'
Firebase 云消息传递 HTTP 协议有相关文档。
运行命令后,您的 Android 设备应该会收到通知。该通知会显示在系统通知中心和控制台日志中。即使应用未运行,您也应该会收到通知,并且在点击通知打开应用后,会在浏览器的控制台日志中看到该通知。
概括
- 无论你选择哪个 React Native 库,你仍然需要知道如何专门针对特定平台设置推送通知。
- 推送通知有多种类型(前台/后台、本地/远程 - 本文重点介绍远程通知,……)。
- 您可以通过发送 HTTP 请求命令,为每个平台推送通知
curl。区别在于身份验证机制,iOS 使用证书,而 Android 使用服务器密钥。每个平台的设置都截然不同。 - 安卓:
- 您需要在 Firebase 控制台中创建一个项目,并将 Android 应用添加到项目中才能获取推送通知密钥。您也可以添加 iOS 应用,但这不是必需的。无论如何,您仍然需要设置 APNs 身份验证密钥并注册 iOS 远程通知。
- iOS:
- 如果你想发送远程通知,必须加入苹果开发者计划。
- 您需要在项目中设置 APNs 身份验证密钥或证书并注册远程通知。
- 无法向在模拟器上运行的应用程序发送推送通知。
- 如果你想发送远程通知,必须加入苹果开发者计划。
我希望这篇文章至少能让你对如何使用 React Native 库在 Android 和 iOS 平台上实现推送通知有一个大致的了解。我的目标并非详细描述所有步骤,而是将我在设置推送通知过程中收集到的信息和链接汇总起来。
文章来源:https://dev.to/jakubkoci/react-native-push-notifications-313i
