【Expo Android 推播整合 03】 裝置註冊:Azure Notification Hub 註冊與程式碼解析

更新 發佈閱讀 17 分鐘

這篇文章將完成把 Android 裝置註冊到 Azure 通知中樞的程式碼。

前置準備

在這篇文章中,你需要事先準備

前導知識

什麼是 APNS 與 FCM?

  • APNs(Apple Push Notification Service):Apple 提供的推播服務,用來將通知送到 Apple 裝置,需先申請 Apple 開發者帳號才能取得。
  • FCM(Firebase Cloud Messaging):Google 提供的推播服務,使用 Firebase SDK 取得。FCM 提供兩種 API:
    • Legacy API:舊版 API,用 server key 傳送請求,較簡單但功能有限,已經在 2024/06 被淘汰。
    • FCM v1(HTTP v1 API):新版 API,使用 OAuth 2.0 認證,支援多平台設定與更高安全性,Google 推薦使用。

Azure 推播通知運作方式

圖片來自 Azure 文件

圖片來自 Azure 文件

上圖來自 Azure 文件,我們可以從中了解 Azure 推播的運作流程。

  1. 裝置向 APNS(Apple)或 FCM(Google)索取推播識別碼,這將作為接收 Azure 的通道。
  2. Azure 使用識別碼,註冊到 Azure 上。
  3. 後端把通知送到通知中樞。
  4. 通知中樞轉給平台 APNS(Apple)或 FCM(Google),由平台推送到裝置。

使用 REST API 註冊 Azure

其實整段程式碼很簡單,但可以使用 REST API 執行的教學藏在 C# 範例裡,我也是先找到很多提供整合的老舊套件,才發現原來 Azure 本身就有提供註冊方法。

1. 取得推播識別碼

安裝 react-native-firebase/messaging,根據 文件中 messaging 提供的 getToken 方法 取得 FCMtoken

npm i @react-native-firebase/messaging

通常裝置每次取得的 FCMtoken 是相同的,但在以下情境時會改變:

import { useEffect } from 'react';
import messaging from '@react-native-firebase/messaging';

export default function HomeScreen() {
useEffect(() => {
const setupPush = async () => {
try {
const token = await messaging().getToken();
console.log(`FCM token: ${token}`);
} catch (err) {
console.log(`初始化推播錯誤 ${JSON.stringify(err)}`)
}
}
setupPush();
}, []);
return (...)
}

2. 準備註冊需要的參數

我們會使用 建立 Azure 註冊 create-registration 這支 API。還記得我們在上一篇文章中有設定 Azure 通知中樞 FCM(v1)金鑰嗎?這支 API 會將剛才產生的 FCM token 註冊到其中。成功註冊的裝置會得到 registerId 等資訊,這未來能用於修改和刪除,建議存到後端。

這是我們註冊需要準備的資料:

  • namespace:Notification Hub 所屬的命名空間(Namespace)
  • NotificationHub:實際 Notification Hub 名稱,是你註冊裝置與推播的實際目標
  • SAStoken:Shared Access Signature

namespace 和 NotificationHub 已經在上一篇文章建立通知中樞時設定好了,本文裡兩個 value 都用 AnnNotify

SAS token

SAStoken 將由以下參數組成,程式碼在 官方文件 有附。

  • targetUrihttps://${HUB_NAMESPACE}.servicebus.windows.net/${HUB_NAME}
  • sharedKey:’Access Policies 中 DefaultListenSharedAccessSignature 的金鑰值’。
  • ruleId:’DefaultListenSharedAccessSignature’。因為共用存取簽章安全性考量,建議 FullSharedAccess 只在後端使用,前端不要用呦。
  • expiresInMins:過期時間(產生後幾分鐘失效),SAStoken失效不影響已經成功的 Azure 註冊。其實建議設定短時間,並且由後端產生較安全,但前端還是可以自己先產出測試。
vocus|新世代的創作平台

我們可以新增一個 hook 專門用來放註冊程式碼,直接從 官方文件 中複製貼上吧!

// hooks/useAzureRegistration.tsx
import axios from 'axios'
import CryptoJS from 'crypto-js'

const HUB_NAME = '通知中樞名稱'
const HUB_NAMESPACE = '通知中樞命名空間'
const SHARED_ACCESS_KEY =
'Access Policies 中 DefaultListenSharedAccessSignature 的金鑰值'
const SHARED_ACCESS_KEY_NAME = 'DefaultListenSharedAccessSignature' // 切記前端不要使用 FullSharedAccess

const registerDeviceToAzure = async (fcmToken: string): Promise<void> => {
const baseUri = `https://${HUB_NAMESPACE}.servicebus.windows.net/${HUB_NAME}`
const apiVersion = '2015-01'
const targetUri = `${baseUri}`

// 生產 SAS token,設定 30 分鐘失效
const sasToken = getSelfSignedToken(
targetUri,
SHARED_ACCESS_KEY,
SHARED_ACCESS_KEY_NAME,
30
)
}

// SAS token 工具
const getSelfSignedToken = function (
targetUri: string,
sharedKey: string,
ruleId: string,
expiresInMins: number
) {
targetUri = encodeURIComponent(targetUri.toLowerCase()).toLowerCase()

// Set expiration in seconds
var expireOnDate = new Date()
expireOnDate.setMinutes(expireOnDate.getMinutes() + expiresInMins)
var expires =
Date.UTC(
expireOnDate.getUTCFullYear(),
expireOnDate.getUTCMonth(),
expireOnDate.getUTCDate(),
expireOnDate.getUTCHours(),
expireOnDate.getUTCMinutes(),
expireOnDate.getUTCSeconds()
) / 1000
var tosign = targetUri + '\n' + expires

// using CryptoJS
var signature = CryptoJS.HmacSHA256(tosign, sharedKey)
var base64signature = signature.toString(CryptoJS.enc.Base64)
var base64UriEncoded = encodeURIComponent(base64signature)

// construct autorization string
var token =
'SharedAccessSignature sr=' +
targetUri +
'&sig=' +
base64UriEncoded +
'&se=' +
expires +
'&skn=' +
ruleId
// console.log("signature:" + token);
return token
}

export default registerDeviceToAzure

3. 註冊 Azure 通知中樞

回到 建立 Azure 註冊 create-registration 這支 API,不同系統裝置有不同註冊範本。這篇文章以 Android 為主,使用 Firebase,所以我的註冊範本 xmlBody 使用 FcmV1TemplateRegistration 的範例,其他系統可以再替換。

另外可以選擇使用以下標籤:

  • Tags:推播時可針對標籤推播,如果要設定只推給 Android 用戶,可使用 <Tags>Android</Tags>。想推給某特定用戶,也可以自訂每個裝置有不同 Id,使用 Id 註冊。
  • ExpirationTime:註冊有效時間。Azure 通知中樞的付費方案與可註冊數量有關,尤其是在開發者測試期間會反覆重新安裝(本文第 1 個步驟有提到 FCMtoken 更新機制),如果不設定有效時間,會累積大量新註冊。雖然有 刪除註冊 API,但一次只能刪一個註冊。
// hooks/useAzureRegistration.tsx
const registerDeviceToAzure = async (fcmToken: string): Promise<void> => {
const baseUri = `https://${HUB_NAMESPACE}.servicebus.windows.net/${HUB_NAME}`;
const apiVersion = '2015-01';
const targetUri = `${baseUri}`;

// 生產 SAS token,設定 30 分鐘失效
const sasToken = getSelfSignedToken(targetUri, SHARED_ACCESS_KEY, SHARED_ACCESS_KEY_NAME, 30);

// Azure 註冊的過期時間設定為 30 天
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + 30);
const isoString = expirationDate.toISOString().replace(/\.\d{3}Z$/, '+08:00');

// FcmV1TemplateRegistration 註冊範本
const xmlBody = `
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<FcmV1RegistrationDescription xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect">
<Tags>...</Tags>
<FcmV1RegistrationId>${fcmToken}</FcmV1RegistrationId>
<ExpirationTime>${isoString}</ExpirationTime>
</FcmV1RegistrationDescription>
</content>
</entry>
`;

try {
const response = await axios.post(`${baseUri}/registrations?api-version=${apiVersion}`, xmlBody, {
headers: {
'Authorization': sasToken,
'Content-Type': 'application/atom+xml'
}
});

// 解析 response 返回註冊頁面顯示
console.log('📡 Azure 註冊成功:', {
status: response.status,
registrationId: response.data?.match(/<title[^>]*>(.*?)<\/title>/)?.[1] ?? '不明',
});
} catch (error: any) {
console.error('❌ Azure 註冊失敗:', error);
return `註冊失敗:${error.message}`;
}
};

// SAS token 工具
const getSelfSignedToken = function (targetUri: string, sharedKey: string, ruleId: string,
expiresInMins: number) {
...
};

export default registerDeviceToAzure;


完工!🎉🎉

接下來幾篇會介紹

  • 要求裝置開啟通知授權
  • 打包 APK


相同文章發布於我的部落格

留言
avatar-img
Ann Chou的沙龍
19會員
32內容數
從藝術領域轉職到前端工程師,喜歡書寫學習歷程和技術文件,掌握經驗與隨時提取的感覺很好。
Ann Chou的沙龍的其他內容
2025/04/27
這篇文章說明如何在 Windows 電腦上設定 Android 推播通知,包含使用 Expo 串接 Firebase 和 Azure 的步驟。文章涵蓋 Firebase 和 Azure 的設定,以及 Android Studio 和 JDK 的配置。
2025/04/27
這篇文章說明如何在 Windows 電腦上設定 Android 推播通知,包含使用 Expo 串接 Firebase 和 Azure 的步驟。文章涵蓋 Firebase 和 Azure 的設定,以及 Android Studio 和 JDK 的配置。
2025/04/20
介紹在 React Native / Expo 中實作推播通知的方式,並比較使用 Expo Notifications 與整合 Firebase Cloud Messaging(FCM)或 Azure Notification Hubs 的差異。
2025/04/20
介紹在 React Native / Expo 中實作推播通知的方式,並比較使用 Expo Notifications 與整合 Firebase Cloud Messaging(FCM)或 Azure Notification Hubs 的差異。
2025/04/19
本篇主題是 React Native 小介紹。 因為先前在測試 Ionic + PWA 開發,對相機功能實在太失望,結果現在我開始用 React Native / Expo 了。 如果還不清楚 Ionic 和 Reac Native 能做不同種類的 App,可以先閱讀 App 種類概述 。
2025/04/19
本篇主題是 React Native 小介紹。 因為先前在測試 Ionic + PWA 開發,對相機功能實在太失望,結果現在我開始用 React Native / Expo 了。 如果還不清楚 Ionic 和 Reac Native 能做不同種類的 App,可以先閱讀 App 種類概述 。
看更多
你可能也想看
Thumbnail
在本篇文章中,將會設定 Cloud Run,以便每當將程式修改並推送到 GitHub 時,它都會使用 Cloud Build 自動構建和部署應用程序的最新版本。
Thumbnail
在本篇文章中,將會設定 Cloud Run,以便每當將程式修改並推送到 GitHub 時,它都會使用 Cloud Build 自動構建和部署應用程序的最新版本。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本課程學習如何在 Kotlin 程式碼檔案中,設定 ImageView 圖片元件,顯示本地端圖片。
Thumbnail
本課程學習如何在 Kotlin 程式碼檔案中,設定 ImageView 圖片元件,顯示本地端圖片。
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
本文提供完成訂閱後的相關事項及安裝指引,包括填寫問卷、遠端開通Trading View帳號、指標安裝步驟等。另外也提供影片教學和紙本教學,以及解決安裝問題的方法。
Thumbnail
本文提供完成訂閱後的相關事項及安裝指引,包括填寫問卷、遠端開通Trading View帳號、指標安裝步驟等。另外也提供影片教學和紙本教學,以及解決安裝問題的方法。
Thumbnail
本課程學習如何使用 Intent 簡單跳頁,切換兩個 Activity。
Thumbnail
本課程學習如何使用 Intent 簡單跳頁,切換兩個 Activity。
Thumbnail
在這篇教學中,我們將學習如何使用 Google Apps Script 來連結 LINE Notify,以便於你的應用程式或自動化工作流程中發送通知。LINE Notify 是 LINE 提供的服務,可以讓你透過 LINE 帳號來發送自訂的通知訊息。
Thumbnail
在這篇教學中,我們將學習如何使用 Google Apps Script 來連結 LINE Notify,以便於你的應用程式或自動化工作流程中發送通知。LINE Notify 是 LINE 提供的服務,可以讓你透過 LINE 帳號來發送自訂的通知訊息。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
本課程學習如何使用 Android Studio 建立的第一個應用程式專案:Hello World。
Thumbnail
本課程學習如何使用 Android Studio 建立的第一個應用程式專案:Hello World。
Thumbnail
本文章將介紹如何在LINE Notify上設定及使用權杖(access token)來進行通知功能。透過此API,可以使用curl或JAVA CODE來讓結果顯示在Line上面,達到及時的通知效果。
Thumbnail
本文章將介紹如何在LINE Notify上設定及使用權杖(access token)來進行通知功能。透過此API,可以使用curl或JAVA CODE來讓結果顯示在Line上面,達到及時的通知效果。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
本篇文章將分享手機App設計教學,並往後介紹使用Flutter開發App的相關知識和技巧。透過這系列的分享,讀者將能夠學習如何利用設計和程式開發技能來製作一個App。文章中也提供了一些靈感來源和教學資源,幫助讀者進行設計和開發的思考和學習。
Thumbnail
本篇文章將分享手機App設計教學,並往後介紹使用Flutter開發App的相關知識和技巧。透過這系列的分享,讀者將能夠學習如何利用設計和程式開發技能來製作一個App。文章中也提供了一些靈感來源和教學資源,幫助讀者進行設計和開發的思考和學習。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News