Expo大作戰(十四)--expo中消息推送的實現

来源:https://www.cnblogs.com/gdsblog/archive/2018/03/13/8556245.html
-Advertisement-
Play Games

簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...


簡要:本系列文章講會對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的設備,這種令牌每次在設備上安裝應用程式時都是唯一的。我們所需要做的就是將此令牌發送到您的伺服器,以便您可以將其與用戶帳戶相關聯,併在將來用於發送推送通知。

import { Permissions, Notifications } from 'expo';

const PUSH_ENDPOINT = 'https://your-server.com/users/push-token';//

async function registerForPushNotificationsAsync() {
  const { status: existingStatus } = await Permissions.getAsync(
    Permissions.NOTIFICATIONS
  );
  let finalStatus = existingStatus;

  // only ask if permissions have not already been determined, because
  // iOS won't necessarily prompt the user a second time.
//僅詢問許可權是否尚未確定,因為
 // iOS不一定會再次提示用戶。
if (existingStatus !== 'granted') { // Android remote notification permissions are granted during the app // install, so this will only ask on iOS
//在應用程式期間授予Android遠程通知許可權
    //安裝,所以這隻會在iOS上詢問
const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS); finalStatus = status; } // Stop here if the user did not grant permissions
//如果用戶沒有授予許可權,請在此停止
if (finalStatus !== 'granted') { return; } // Get the token that uniquely identifies this device
//獲取唯一標識此設備的令牌
let token = await Notifications.getExpoPushTokenAsync(); // POST the token to your backend server from where you can retrieve it to send push notifications.
//將令牌發佈到您的後端伺服器,您可以從中檢索該令牌以發送推送通知。
return fetch(PUSH_ENDPOINT, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ token: { value: token, }, user: { username: 'Brent', }, }), }); }

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對象。

import React from 'react';
import {
  Notifications,
} from 'expo';
import {
  Text,
  View,
} from 'react-native';

import registerForPushNotificationsAsync from 'registerForPushNotificationsAsync';

export default class AppContainer extends React.Component {
  state = {
    notification: {},
  };

  componentWillMount() {
    registerForPushNotificationsAsync();

    // Handle notifications that are received or selected while the app
    // is open. If the app was closed and then opened by tapping the
    // notification (rather than just tapping the app icon to open it),
    // this function will fire on the next tick after the app starts
    // with the notification data.
// 處理在應用程式中接收或選擇的通知
     // 當他們在打開狀態。 如果應用程式已關閉,然後通過點擊打開應用程式
     // 通知(而不是只是點擊應用程式圖標打開它),
     // 這個函數會在應用程式啟動後觸發下一個勾子
     // 與通知數據。

this._notificationSubscription = Notifications.addListener(this._handleNotification); } _handleNotification = (notification) => { this.setState({notification: notification}); }; render() { return ( <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}> <Text>Origin: {this.state.notification.origin}</Text> <Text>Data: {JSON.stringify(this.state.notification.data)}</Text> </View> ); } }

通知處理時間

從上面的情況來看,根據收到通知時的狀態,您的應用程式能夠處理通知的時間並不完全清楚。 詳細,請參閱下表:

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:)

accept: application/json
accept-encoding: gzip, deflate
content-type: application/json


此API目前不需要任何身份驗證。

這是一個使用cURL的“hello world”請求(用您自己的替換占位符推送令牌):

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

HTTP請求正文必須是JSON。 它可以是單個消息對象或最多100個消息的數組。 我們建議您在發送多個郵件時儘量使用數組,以便有效減少需要向Expo伺服器發送的請求數量。 這是發送兩條消息的示例請求主體:

[{
  "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
  "sound": "default",
  "body": "Hello world!"
}, {
  "to": "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
  "badge": 1,
  "body": "You've got mail"
}]
//完整代碼這樣
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" }]
'
 

一旦成功,HTTP響應將是一個JSON對象,其數據欄位是一個推送收據數組,每個對應於請求中相應索引處的消息。 繼續上面的例子,這是一個成功的響應主體的樣子:

{
  "data": [
    {"status": "ok"},
    {"status": "ok"}
  ]
}

當傳遞消息時出錯時,收據的狀態將為“錯誤”,並且收據將包含有關錯誤的信息。 有關響應格式的更多信息記錄如下。

     註意:即使收據顯示“OK”,也不能保證設備已收到信息; “OK”表示我們已成功將消息發送給Android或iOS推送通知服務。 例如,如果收件人設備處於關閉狀態,則Android或iOS推送通知服務將嘗試傳遞消息,但設備不一定會收到該消息。

如果您發送單個未包裝在數組中的消息,則數據欄位將為未包裝在數組中的推送收據。


消息格式

每條消息必須是具有給定欄位的JSON對象:

type PushMessage = {
  /**
   * An Expo push token specifying the recipient of this message.
* Expo推送令牌,指定此消息的收件人。
*/ to: string, /** * A JSON object delivered to your app. It may be up to about 4KiB; the total * notification payload sent to Apple and Google must be at most 4KiB or else * you will get a "Message Too Big" error.
*一個JSON對象傳遞給你的應用程式。 它可能高達約4KiB; 總數
    *發送給Apple和Google的通知有效負載必須最大為4KiB或其他
    *你會得到一個“消息太大”的錯誤。
*/ data?: Object, /** * The title to display in the notification. Devices often display this in * bold above the notification body. Only the title might be displayed on * devices with smaller screens like Apple Watch.
*通知中顯示的標題。 設備經常在此顯示
    *在通知主體上方加粗。 只有標題可能會顯示在上面
    * Apple Watch等小屏幕設備。
*/ title?: string, /** * The message to display in the notification
  *要在通知中顯示的消息
*/ body?: string, /** * A sound to play when the recipient receives this notification. Specify * "default" to play the device's default notification sound, or omit this * field to play no sound.
*收件人收到此通知時播放的聲音。指定
    *“預設”播放設備的預設通知聲音,或省略此
    *現場不播放聲音。
*/ sound?: 'default' | null, /** * Time to Live: the number of seconds for which the message may be kept * around for redelivery if it hasn't been delivered yet. Defaults to 0. * * On Android, we make a best effort to deliver messages with zero TTL * immediately and do not throttle them * * This field takes precedence over `expiration` when both are specified.
  *生存時間:可以保留消息的秒數
    *如果還沒有交付,請重新發送。 預設為0。
   *
    *在Android上,我們盡最大努力以零TTL傳遞消息
    *立即,不要扼殺他們
   *
    *這兩個欄位在指定時優先於`expiration`。
*/ ttl?: number, /** * A timestamp since the UNIX epoch specifying when the message expires. This * has the same effect as the `ttl` field and is just an absolute timestamp * instead of a relative time.
*自UNIX紀元指定消息到期時的時間戳。 這個
    *與`ttl`欄位具有相同的效果,並且只是一個絕對時間戳
    *而不是相對時間。
*/ expiration?: number, /** * The delivery priority of the message. Specify "default" or omit this field * to use the default priority on each platform, which is "normal" on Android * and "high" on iOS. * * On Android, normal-priority messages won't open network connections on * sleeping devices and their delivery may be delayed to conserve the battery. * High-priority messages are delivered immediately if possible and may wake * sleeping devices to open network connections, consuming energy. * * On iOS, normal-priority messages are sent at a time that takes into account * power considerations for the device, and may be grouped and delivered in * bursts. They are throttled and may not be delivered by Apple. High-priority * messages are sent immediately. Normal priority corresponds to APNs priority * level 5 and high priority to 10.
*消息的傳遞優先順序。 指定“預設”或省略此欄位
    *在每個平臺上使用預設優先順序,在Android上為“正常”
    *和iOS上的“高”。
   *
    *在Android上,普通優先順序消息不會打開網路連接
    *睡眠設備及其交付可能會延遲以節省電池。
    *如果可能,高優先順序消息會立即傳送並可能喚醒
    *睡覺設備打開網路連接,消耗能源。
   *
    *在iOS上,正常優先順序消息會在考慮時發送
    *設備的功耗考慮因素,可能會被分組和交付
    *爆發。 它們受到限制,可能無法由Apple提供。高優先順序
    *消息立即發送。 正常優先順序對應於APN優先順序
    * 5級,高優先順序為10。
*/ priority?: 'default' | 'normal' | 'high', // iOS-specific fields /** * Number to display in the badge on the app icon. Specify zero to clear the * badge.
*號碼顯示在應用程式圖標上的徽章中。 指定零來清除
    *徽章。
*/ badge?: number, }

響應格式

響應是一個帶有兩個可選欄位,數據和錯誤的JSON對象。 如果整個請求出現錯誤,那麼HTTP狀態碼將是4xx或5xx,並且錯誤將是一個錯誤對象數組(通常只有一個):

 

{
  "errors": [{
    "code": "INTERNAL_SERVER_ERROR",
    "message": "An unknown error occurred."
  }]
}

如果存在影響單個消息但不是整個請求的錯誤,則HTTP狀態代碼將為200,錯誤欄位將為空,並且數據欄位將包含描述錯誤的推送收據:

{
  "data": [{
    "status": "error",
    "message": "\"ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]\" is not a registered push notification recipient",
    "details": {
      "error": "DeviceNotRegistered"
    }
  }]
}

如果所有消息都已成功傳送到Android和iOS推送通知服務,則HTTP狀態碼也將為200。

重要說明:特別是,查找具有錯誤欄位的詳細信息對象。如果存在,它可能是以下值之一:DeviceNotRegistered,MessageTooBig,MessageRateExceeded和InvalidCredentials。你應該像這樣處理這些錯誤:

    DeviceNotRegistered:設備不能再接收推送通知,您應該停止向給定的expo推送令牌發送消息。

    MessageTooBig:總通知有效負載太大。在Android和iOS上,總有效負載不得超過4096位元組。

    MessageRateExceeded:您發送消息的頻率太高,無法給定設備。實施指數退避並慢慢重試發送消息。

    InvalidCredentials:您的獨立應用程式的推送通知憑證無效(例如:您可能已撤銷它們)。運行exp build:ios -c為iOS重新生成新推送通知憑證。

如果我們無法將消息傳遞給Android或iOS推送通知服務,則收據的詳細信息可能還包括特定於服務的信息。這主要用於調試和報告可能的錯誤給我們。


下一張繼續介紹,這一篇主要介紹了:expo的消息推送機制, 歡迎大家關註我的微信公眾號,這篇文章是否被大家認可,我的衡量標準就是公眾號粉絲增長人數。歡迎大家轉載,但必須保留本人博客鏈接!

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [root@VM_0_7_centos data]# vim /etc/my.cnf [root@VM_0_7_centos data]# vim /etc/my.cnf [root@VM_0_7_centos data]# /etc/init.d/mysqld restart Shutting d... ...
  • 1.啟動mysql時,一直不成功,查看錯誤日誌 /var/log/mysql/error.log 2.主要的錯誤信息有如下幾條: 3.查詢後是因為記憶體不足,查看記憶體 增加swap交換空間解決問題: 4.增加自動掛載: 在文件/etc/fstab中加入 /swapfile swap swap defa ...
  • ...
  • 前言 今天筆者要介紹的是hive相關的內容,會從概念到安裝,然後之後再一步一步深入介紹相關知識。 一、hive的相關介紹 1.1hive的相關定義 hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射為一張資料庫表,並提供簡單的sql查詢功能,可以將sql語句轉換為MapRedu ...
  • Android P開始逐步限制特定非 SDK 介面的訪問許可權,並要求開發者使用公開 API 里的替代介面。針對該特性,更新了Android遠程桌面助手,目前支持Android P開發者預覽版。 ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
  • 最近項目上需要開發掃描二維碼進行簽到的功能,主要用於開會簽到的場景,所以為了避免作弊,我們再開發時只採用直接掃描的方式,並且要屏蔽從相冊讀取圖片,此外還在二維碼掃描成功簽到時後臺會自動上傳用戶的當前地點,如何自動定位獲取用戶的當前地點在上一篇隨筆iOS學習——自動定位中已經講過了,本文就簡單地說一下 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...