简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网

我猜去全部机翻+个人修改补充+demo测试的形式,对expo进行一次大补血!欢迎加入expo兴趣学习交流群:597732981

【之前我写过一些列关于expo和rn入门配置的东i西,大家可以点击这里查看:从零学习rn开发

相关文章:

Expo大作战(一)--什么是expo,如何安装expo clinet和xde,xde如何使用

Expo大作战(二)--expo的生命周期,expo社区交流方式,expo学习必备资源,开发使用expo时关注的一些问题

Expo大作战(三)--针对已经开发过react native项目开发人员有针对性的介绍了expo,expo的局限性,开发时项目选型注意点等

Expo大作战(四)--快速用expo构建一个app,expo中的关键术语

Expo大作战(五)--expo中app.json 文件的配置信息

Expo大作战(六)--expo开发模式,expo中exp命令行工具,expo中如何查看日志log,expo中的调试方式

Expo大作战(七)--expo如何使用Genymotion模拟器

Expo大作战(八)--expo中的publish以及expo中的link,对link这块东西没有详细看,大家可以来和我交流

更多>>

接下来就开始撸码


推送通知

推动通知是一个重要特性,因为“增长黑客”会说(Push Notifications are an important feature to, as “growth hackers” would say, ),保留并重新吸引用户,并通过他们的注意力货币化等等。从我的角度来看,只需知道相关事件何时发生在应用程序中便可方便使用,这样我就可以跳回来阅读更多内容。让我们看看expo如何与做到这一点。扰流警报:这几乎太简单了(Spoiler alert: it’s almost too easy)。

注意:iOS和Android模拟器无法接收推送通知。要测试它们,您需要使用真实设备。此外,在模拟器上调用Permissions.askAsync时,无论您是否选择允许,它都会立即以“未确定”状态作为状态解决。

连接推送通知有三个主要步骤:发送用户的Expo Push Token到您的服务器,当您想发送通知时使用令牌调用Expo的Push API,并且响应接收 and/or 选择应用程序中的通知(例如跳转到通知所指的特定屏幕)。

1.将用户的Expo Push Token保存在服务器上

为了向其他人发送推送通知,我们需要了解他们的设备。当然,我们自己知道我们用户的帐户信息,但Apple,Google和Expo不了解您的专有用户帐户系统中与“Brent”相对应的设备。Expo负责通过expo推送令牌识别Apple和Google的设备,这种令牌每次在设备上安装应用程序时都是唯一的。我们所需要做的就是将此令牌发送到您的服务器,以便您可以将其与用户帐户相关联,并在将来用于发送推送通知。

  1. import { Permissions, Notifications } from 'expo';
  2.  
  3. const PUSH_ENDPOINT = 'https://your-server.com/users/push-token';//
  4.  
  5. async function registerForPushNotificationsAsync() {
  6. const { status: existingStatus } = await Permissions.getAsync(
  7. Permissions.NOTIFICATIONS
  8. );
  9. let finalStatus = existingStatus;
  10.  
  11. // only ask if permissions have not already been determined, because
  12. // iOS won't necessarily prompt the user a second time.
    //仅询问权限是否尚未确定,因为
     // iOS不一定会再次提示用户。
  13. if (existingStatus !== 'granted') {
  14. // Android remote notification permissions are granted during the app
  15. // install, so this will only ask on iOS
    //在应用程序期间授予Android远程通知权限
        //安装,所以这只会在iOS上询问
  16. const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
  17. finalStatus = status;
  18. }
  19.  
  20. // Stop here if the user did not grant permissions
    //如果用户没有授予权限,请在此停止
  21. if (finalStatus !== 'granted') {
  22. return;
  23. }
  24.  
  25. // Get the token that uniquely identifies this device
    //获取唯一标识此设备的令牌
  26. let token = await Notifications.getExpoPushTokenAsync();
  27.  
  28. // POST the token to your backend server from where you can retrieve it to send push notifications.
    //将令牌发布到您的后端服务器,您可以从中检索该令牌以发送推送通知。
  29. return fetch(PUSH_ENDPOINT, {
  30. method: 'POST',
  31. headers: {
  32. Accept: 'application/json',
  33. 'Content-Type': 'application/json',
  34. },
  35. body: JSON.stringify({
  36. token: {
  37. value: token,
  38. },
  39. user: {
  40. username: 'Brent',
  41. },
  42. }),
  43. });
  44. }

2.用用户令牌调用Expo的Push API

推送通知必须来自某个地方,并且某个地方是您的服务器,可能(如果您想要,您可以编写一个命令行工具来发送它们,它们都是一样的)。 当您准备发送推送通知时,请将expo推送令牌从用户记录中取出,并使用普通的旧HTTPS POST请求将其发送到Expo API。 我们已经采取了几种语言为您打包:

如果您想以其他语言实现它,请查看源代码。

Expo推送通知工具对于在开发过程中测试推送通知也很有用。它可让您轻松地将测试通知发送到您的设备。

3.处理接收和/或选择通知(Handle receiving and/or selecting the notification)

对于Android来说,这一步完全是可选的 - 如果您的通知纯粹是信息性的,而您在接收或选择时不想处理它们,那么您已经完成了。通知将出现在系统通知托盘中,正如您期望的那样,点击它们可以打开/关闭应用程序。

对于iOS来说,处理推送通知是明智的,因为否则用户将永远看不到它们。系统通知列表中不会显示在iOS上预先登录应用程序时发出的通知。通常的解决方案是只手动显示通知。例如,如果您在Messenger for iOS上收到消息,请将应用程序预先安排好,但没有打开此对话,您将看到通知从自定义通知用户界面的屏幕顶部向下滑动。

幸运的是,处理推送通知对于Expo来说很简单,您只需将侦听器添加到Notifications对象。

  1. import React from 'react';
  2. import {
  3. Notifications,
  4. } from 'expo';
  5. import {
  6. Text,
  7. View,
  8. } from 'react-native';
  9.  
  10. import registerForPushNotificationsAsync from 'registerForPushNotificationsAsync';
  11.  
  12. export default class AppContainer extends React.Component {
  13. state = {
  14. notification: {},
  15. };
  16.  
  17. componentWillMount() {
  18. registerForPushNotificationsAsync();
  19.  
  20. // Handle notifications that are received or selected while the app
  21. // is open. If the app was closed and then opened by tapping the
  22. // notification (rather than just tapping the app icon to open it),
  23. // this function will fire on the next tick after the app starts
  24. // with the notification data.
    // 处理在应用程序中接收或选择的通知
         // 当他们在打开状态。 如果应用程序已关闭,然后通过点击打开应用程序
         // 通知(而不是只是点击应用程序图标打开它),
         // 这个函数会在应用程序启动后触发下一个勾子
         // 与通知数据。
  25. this._notificationSubscription = Notifications.addListener(this._handleNotification);
  26. }
  27.  
  28. _handleNotification = (notification) => {
  29. this.setState({notification: notification});
  30. };
  31.  
  32. render() {
  33. return (
  34. <View style={{flex: , justifyContent: 'center', alignItems: 'center'}}>
  35. <Text>Origin: {this.state.notification.origin}</Text>
  36. <Text>Data: {JSON.stringify(this.state.notification.data)}</Text>
  37. </View>
  38. );
  39. }
  40. }

通知处理时间

从上面的情况来看,根据收到通知时的状态,您的应用程序能够处理通知的时间并不完全清楚。 详细,请参阅下表:

HTTP / 2 API

虽然有几种语言的服务器端SDK可以帮助您发送推送通知,但您可能希望直接通过HTTP / 2 API发送请求。

  • 发送通知

使用以下HTTP标头向https://exp.host/--/api/v2/push/send发送POST请求:(Send a POST request to https://exp.host/--/api/v2/push/send with the following HTTP headers:)

  1. accept: application/json
  2. accept-encoding: gzip, deflate
  3. content-type: application/json

此API目前不需要任何身份验证。

这是一个使用cURL的“hello world”请求(用您自己的替换占位符推送令牌):

  1. curl -H "Content-Type: application/json" -X POST https://exp.host/--/api/v2/push/send -d '{
  2. "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
  3. "title":"hello",
  4. "body": "world"
  5. }'

HTTP请求正文必须是JSON。 它可以是单个消息对象或最多100个消息的数组。 我们建议您在发送多个邮件时尽量使用数组,以便有效减少需要向Expo服务器发送的请求数量。 这是发送两条消息的示例请求主体:

  1. [{
  2. "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
  3. "sound": "default",
  4. "body": "Hello world!"
  5. }, {
  6. "to": "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
  7. "badge": ,
  8. "body": "You've got mail"
  9. }]
    //完整代码这样
  1. curl -H "Content-Type: application/json" -X POST https://exp.host/--/api/v2/push/send -d '[
    { "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]", "sound": "default", "body": "Hello world!" },
    { "to": "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]", "badge": 1, "body": "You've got mail" }]'
  1.  

一旦成功,HTTP响应将是一个JSON对象,其数据字段是一个推送收据数组,每个对应于请求中相应索引处的消息。 继续上面的例子,这是一个成功的响应主体的样子:

  1. {
  2. "data": [
  3. {"status": "ok"},
  4. {"status": "ok"}
  5. ]
  6. }

当传递消息时出错时,收据的状态将为“错误”,并且收据将包含有关错误的信息。 有关响应格式的更多信息记录如下。

注意:即使收据显示“OK”,也不能保证设备已收到信息; “OK”表示我们已成功将消息发送给Android或iOS推送通知服务。 例如,如果收件人设备处于关闭状态,则Android或iOS推送通知服务将尝试传递消息,但设备不一定会收到该消息。

如果您发送单个未包装在数组中的消息,则数据字段将为未包装在数组中的推送收据。

消息格式

每条消息必须是具有给定字段的JSON对象:

  1. type PushMessage = {
  2. /**
  3. * An Expo push token specifying the recipient of this message.
    * Expo推送令牌,指定此消息的收件人。
  4. */
  5. to: string,
  6.  
  7. /**
  8. * A JSON object delivered to your app. It may be up to about 4KiB; the total
  9. * notification payload sent to Apple and Google must be at most 4KiB or else
  10. * you will get a "Message Too Big" error.
    *一个JSON对象传递给你的应用程序。 它可能高达约4KiB; 总数
        *发送给Apple和Google的通知有效负载必须最大为4KiB或其他
        *你会得到一个“消息太大”的错误。
  11. */
  12. data?: Object,
  13.  
  14. /**
  15. * The title to display in the notification. Devices often display this in
  16. * bold above the notification body. Only the title might be displayed on
  17. * devices with smaller screens like Apple Watch.
    *通知中显示的标题。 设备经常在此显示
        *在通知主体上方加粗。 只有标题可能会显示在上面
        * Apple Watch等小屏幕设备。
  18. */
  19. title?: string,
  20.  
  21. /**
  22. * The message to display in the notification
      *要在通知中显示的消息
  23. */
  24. body?: string,
  25.  
  26. /**
  27. * A sound to play when the recipient receives this notification. Specify
  28. * "default" to play the device's default notification sound, or omit this
  29. * field to play no sound.
    *收件人收到此通知时播放的声音。指定
        *“默认”播放设备的默认通知声音,或省略此
        *现场不播放声音。
  30. */
  31. sound?: 'default' | null,
  32.  
  33. /**
  34. * Time to Live: the number of seconds for which the message may be kept
  35. * around for redelivery if it hasn't been delivered yet. Defaults to 0.
  36. *
  37. * On Android, we make a best effort to deliver messages with zero TTL
  38. * immediately and do not throttle them
  39. *
  40. * This field takes precedence over `expiration` when both are specified.
      *生存时间:可以保留消息的秒数
        *如果还没有交付,请重新发送。 默认为0。
       *
        *在Android上,我们尽最大努力以零TTL传递消息
        *立即,不要扼杀他们
       *
        *这两个字段在指定时优先于`expiration`。
  41. */
  42. ttl?: number,
  43.  
  44. /**
  45. * A timestamp since the UNIX epoch specifying when the message expires. This
  46. * has the same effect as the `ttl` field and is just an absolute timestamp
  47. * instead of a relative time.
    *自UNIX纪元指定消息到期时的时间戳。 这个
        *与`ttl`字段具有相同的效果,并且只是一个绝对时间戳
        *而不是相对时间。
  48. */
  49. expiration?: number,
  50.  
  51. /**
  52. * The delivery priority of the message. Specify "default" or omit this field
  53. * to use the default priority on each platform, which is "normal" on Android
  54. * and "high" on iOS.
  55. *
  56. * On Android, normal-priority messages won't open network connections on
  57. * sleeping devices and their delivery may be delayed to conserve the battery.
  58. * High-priority messages are delivered immediately if possible and may wake
  59. * sleeping devices to open network connections, consuming energy.
  60. *
  61. * On iOS, normal-priority messages are sent at a time that takes into account
  62. * power considerations for the device, and may be grouped and delivered in
  63. * bursts. They are throttled and may not be delivered by Apple. High-priority
  64. * messages are sent immediately. Normal priority corresponds to APNs priority
  65. * level 5 and high priority to 10.
    *消息的传递优先级。 指定“默认”或省略此字段
        *在每个平台上使用默认优先级,在Android上为“正常”
        *和iOS上的“高”。
       *
        *在Android上,普通优先级消息不会打开网络连接
        *睡眠设备及其交付可能会延迟以节省电池。
        *如果可能,高优先级消息会立即传送并可能唤醒
        *睡觉设备打开网络连接,消耗能源。
       *
        *在iOS上,正常优先级消息会在考虑时发送
        *设备的功耗考虑因素,可能会被分组和交付
        *爆发。 它们受到限制,可能无法由Apple提供。高优先级
        *消息立即发送。 正常优先级对应于APN优先级
        * 5级,高优先级为10。
  66. */
  67. priority?: 'default' | 'normal' | 'high',
  68.  
  69. // iOS-specific fields
  70.  
  71. /**
  72. * Number to display in the badge on the app icon. Specify zero to clear the
  73. * badge.
    *号码显示在应用程序图标上的徽章中。 指定零来清除
        *徽章。
  74. */
  75. badge?: number,
  76. }

响应格式

响应是一个带有两个可选字段,数据和错误的JSON对象。 如果整个请求出现错误,那么HTTP状态码将是4xx或5xx,并且错误将是一个错误对象数组(通常只有一个):

  1. {
  2. "errors": [{
  3. "code": "INTERNAL_SERVER_ERROR",
  4. "message": "An unknown error occurred."
  5. }]
  6. }

如果存在影响单个消息但不是整个请求的错误,则HTTP状态代码将为200,错误字段将为空,并且数据字段将包含描述错误的推送收据:

  1. {
  2. "data": [{
  3. "status": "error",
  4. "message": "\"ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]\" is not a registered push notification recipient",
  5. "details": {
  6. "error": "DeviceNotRegistered"
  7. }
  8. }]
  9. }

如果所有消息都已成功传送到Android和iOS推送通知服务,则HTTP状态码也将为200。

重要说明:特别是,查找具有错误字段的详细信息对象。如果存在,它可能是以下值之一:DeviceNotRegistered,MessageTooBig,MessageRateExceeded和InvalidCredentials。你应该像这样处理这些错误:

DeviceNotRegistered:设备不能再接收推送通知,您应该停止向给定的expo推送令牌发送消息。

MessageTooBig:总通知有效负载太大。在Android和iOS上,总有效负载不得超过4096字节。

MessageRateExceeded:您发送消息的频率太高,无法给定设备。实施指数退避并慢慢重试发送消息。

InvalidCredentials:您的独立应用程序的推送通知凭证无效(例如:您可能已撤销它们)。运行exp build:ios -c为iOS重新生成新推送通知凭证。

如果我们无法将消息传递给Android或iOS推送通知服务,则收据的详细信息可能还包括特定于服务的信息。这主要用于调试和报告可能的错误给我们。


下一张继续介绍,这一篇主要介绍了:expo的消息推送机制, 欢迎大家关注我的微信公众号,这篇文章是否被大家认可,我的衡量标准就是公众号粉丝增长人数。欢迎大家转载,但必须保留本人博客链接!

Expo大作战(十四)--expo中消息推送的实现的更多相关文章

  1. Expo大作战(十五)--expo中splash启动页的详细机制

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  2. Expo大作战(十二)--expo中的自定义样式Custom font,以及expo中的路由Route&Navigation

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  3. Expo大作战(十九)--expo打包后,发布分用程序到商店的注意事项

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  4. Expo大作战(十八)--expo如何发布成独立应用程序,打包成apk或者ipa,发布到对应应用商店

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  5. Expo大作战(十六)--expo结合firebase 一个nosql数据库(本章令我惊讶但又失望!)

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  6. 现代IM系统中消息推送和存储架构的实现

    现代IM系统中消息推送和存储架构的实现-云栖社区-阿里云 https://yq.aliyun.com/articles/253242

  7. Expo大作战(十)--expo中的App Icon,expo中的Assets,expo中的ErrorHandling错误处理

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  8. Expo大作战(三十一)--expo sdk api之Payments(expo中的支付),翻译这篇文章傻逼了,完全不符合国内用户,我只负责翻译大家可以略过!

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  9. Expo大作战(二十三)--expo中expo kit 高级属性(没干货)

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

随机推荐

  1. IntelliJ IDEA导入多个eclipse项目到同一个workspace下

    IntelliJ IDEA 与eclipse在新建项目上工作区的叫法略有不同,区别见下图. 我们在eclipse都是在新建的workspace目录下新建我们的项目,但是在IDEA中没有workspac ...

  2. Spring Cloud Eureka 实现服务注册与发现

    微服务 是一种架构模式,跟具体的语言实现无关,微服务架构将业务逻辑分散到了各个服务当中,服务间通过网络层进行通信共同协作:这样一个应用就可以划分为多个服务单独来维护发布.构建一个可靠微服务系统是需要具 ...

  3. JNI 简单例子

    原文:http://www.cnblogs.com/youxilua/archive/2011/09/16/2178554.html 1,先把c语言的编译环境搭建好,windows下这里使用mingw ...

  4. PHP-引入文件(include)后,页面错位,不居中解决办法

    1.把include文件放在head里,不要放在html或doctype上面,这样可以解决居中的问题,空白行的话可以用<div style="display:none"> ...

  5. JavaScript -- Opener

    -----028-Window-Opener.html----- <!DOCTYPE html> <html> <head> <meta http-equiv ...

  6. scala-03-list操作

    列表 Scala 列表类似于数组,它们所有元素的类型都相同,但是它们也有所不同:列表是不可变的,值一旦被定义了就不能改变,其次列表 具有递归的结构(也就是链接表结构)而数组不是.. 1, 创建 lis ...

  7. Python虚拟环境工具-Virtualenv 介绍及部署记录

    在开发Python应用程序时,系统默认的Python版本可能会不兼容这个应用程序, 如果同时开发多个应用程序, 可能会用到好几个版本的python环境, 这种情况下,每个应用可能需要各自拥有一套&qu ...

  8. 第2章 Selenium2-java 测试环境搭建

    2.1  Window下环境搭建 2.1.1 安装Java 2.1.2 安装Eclipse (网上资源很多,就不详将了). 2.1.3 下载Java版的Selenium包. 下载地址:http://d ...

  9. 网络之Json生成解析

    // // ViewController.m // Json // // Created by City--Online on 15/4/28. // Copyright (c) 2015年 CYW. ...

  10. [转]WordPress主题开发:主题初始化

    本文转自:http://www.cnblogs.com/tinyphp/p/4391182.html 在最简单的情况下,一个WordPress主题由两个文件构成: index.php -------- ...