You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求React Native集成Amazon SNS推送的教程或代码库,设备注册后收不到消息

问题诊断与修复方案

核心问题:错误使用Expo Push Token而非原生设备令牌

AWS SNS的Platform Endpoint需要的是原生APNs/iOS令牌或FCM/Android令牌,你当前调用Notifications.getExpoPushTokenAsync()获取的是Expo推送服务的中转令牌,并非设备直接对接APNs/FCM的原生令牌,这是收不到推送的关键原因。

关键修复步骤

  • 区分iOS/Android对应的SNS Platform ARN
  • 替换令牌获取方式为原生设备令牌
  • 确保权限授予后再执行SNS注册逻辑
  • 添加通知监听器处理推送接收与交互

完整修正代码

import { StatusBar } from "expo-status-bar";
import { useEffect } from "react";
import { StyleSheet, Text, View, Platform } from "react-native";
import AWS from "aws-sdk";
import * as Notifications from "expo-notifications";
import {
  AWS_ACCESS_KEY,
  AWS_SECRET_ACCESS_KEY,
  REGION,
  TOPIC_ARN,
  PLATFORM_ARN, // Android Platform ARN
  IOS_PLATFORM_ARN, // iOS Platform ARN
  EXPO_PROJECT_ID,
} from "@env";

// 全局配置通知展示规则
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

export default function App() {
  useEffect(() => {
    const setupNotifications = async () => {
      // 1. 请求通知权限,未授予则终止流程
      const { status } = await Notifications.requestPermissionsAsync();
      if (status !== "granted") {
        console.log("通知权限被拒绝");
        return;
      }

      // 2. 获取原生设备令牌(对接APNs/FCM的令牌)
      let deviceToken;
      try {
        const tokenResponse = await Notifications.getDevicePushTokenAsync();
        deviceToken = tokenResponse.data;
        console.log("原生设备令牌:", deviceToken);
      } catch (error) {
        console.log("获取原生令牌失败:", error);
        return;
      }

      // 3. 初始化AWS SNS客户端
      AWS.config.update({
        region: REGION,
        accessKeyId: AWS_ACCESS_KEY,
        secretAccessKey: AWS_SECRET_ACCESS_KEY,
      });
      const SNS = new AWS.SNS({ correctClockSkew: true });

      // 4. 根据平台选择对应的SNS Platform ARN
      const platformApplicationArn = Platform.OS === "ios" 
        ? IOS_PLATFORM_ARN 
        : PLATFORM_ARN;

      try {
        // 创建SNS平台端点
        const endpointParams = {
          PlatformApplicationArn: platformApplicationArn,
          Token: deviceToken,
        };
        const createEndpointResponse = await SNS.createPlatformEndpoint(endpointParams).promise();
        const endpointArn = createEndpointResponse.EndpointArn;
        console.log("SNS端点创建成功:", endpointArn);

        // 订阅端点到目标主题
        const subscribeParams = {
          TopicArn: TOPIC_ARN,
          Protocol: "Application",
          Endpoint: endpointArn,
        };
        await SNS.subscribe(subscribeParams).promise();
        console.log("成功订阅SNS主题");
      } catch (error) {
        console.log("SNS注册/订阅失败:", error);
      }
    };

    // 添加通知监听:接收通知、处理点击事件
    const notificationListener = Notifications.addNotificationReceivedListener(notification => {
      console.log("收到推送通知:", notification);
    });
    const responseListener = Notifications.addNotificationResponseReceivedListener(response => {
      console.log("通知被点击:", response);
    });

    // 执行初始化流程
    setupNotifications();

    // 组件卸载时清理监听
    return () => {
      Notifications.removeNotificationSubscription(notificationListener);
      Notifications.removeNotificationSubscription(responseListener);
    };
  }, []);

  return (
    <View style={styles.container}>
      <Text>AWS SNS 推送测试</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

额外排查要点

  • 检查SNS平台应用配置
    • iOS:确认APNs证书已上传到SNS,且证书环境(开发/生产)与你的Expo构建环境一致
    • Android:确认FCM服务器密钥已正确配置到SNS的Android平台应用中
  • 验证SNS端点状态
    在AWS控制台查看对应设备端点的状态,若为Disabled,检查令牌有效性或平台配置是否有误
  • 直接测试端点推送
    跳过主题订阅,调用SNS的publish接口直接向端点ARN推送测试消息,确认推送链路是否通畅
  • 使用独立包测试
    Expo Go测试环境对推送支持有限,建议用expo build:ios/expo build:android构建独立包进行测试

内容的提问来源于stack exchange,提问作者Dan Cruz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:37:46