如何在React Native中订阅Salesforce Platform Event通知
在React Native中使用Salesforce Pub/Sub API订阅Platform Events
原代码的核心问题
- 订阅函数未触发:
setPEvents仅定义但从未被调用,拿到Salesforce会话凭证后没有执行订阅逻辑 - API端点错误:Pub/Sub API的订阅端点不是
/event/${eventName}/subscriptions,正确的通用订阅路径为/services/data/vXX.X/pub-sub/subscriptions - 缺少消息拉取逻辑:创建订阅只是第一步,单次POST请求无法持续接收事件推送,需要通过轮询拉取后续消息
修正后的完整实现代码
import {View, Text} from 'react-native'; import React, { useEffect, useState } from 'react'; import { oauth } from 'react-native-force'; function History() { const [session, setSession] = useState(null); const eventName = "Test_PE__e"; const [replayMode] = useState("ALL"); // ALL接收所有事件,LATEST只接收订阅后的新事件 const [subscription, setSubscription] = useState(null); const [receivedEvents, setReceivedEvents] = useState([]); let pollTimer = null; // 处理登录与会话初始化 useEffect(() => { oauth.getAuthCredentials( (authData) => { console.log("已获取会话凭证", authData); setSession(authData); }, () => { oauth.authenticate( (newAuthData) => setSession(newAuthData), (error) => console.log('认证失败:' + error) ); } ); // 组件卸载时清理轮询定时器 return () => { if (pollTimer) clearInterval(pollTimer); }; }, []); // 会话更新时自动创建订阅 useEffect(() => { if (session) initSubscription(session); }, [session]); // 创建Pub/Sub订阅 async function initSubscription(session) { const headers = new Headers({ 'Authorization': `Bearer ${session.accessToken}`, 'Content-Type': 'application/json' }); const requestBody = { "topicName": `/event/${eventName}`, "replayPreset": replayMode }; const subscribeUrl = `${session.instanceUrl}/services/data/v57.0/pub-sub/subscriptions`; try { const response = await fetch(subscribeUrl, { method: 'POST', headers: headers, body: JSON.stringify(requestBody) }); if (!response.ok) throw new Error(`订阅请求失败,状态码: ${response.status}`); const subInfo = await response.json(); setSubscription(subInfo); console.log("订阅成功,ID:", subInfo.id); // 启动消息轮询 startMessagePolling(subInfo.id, session); } catch (err) { console.log('订阅出错:', err); } } // 轮询拉取事件消息 async function startMessagePolling(subId, session) { const headers = new Headers({ 'Authorization': `Bearer ${session.accessToken}` }); const pollUrl = `${session.instanceUrl}/services/data/v57.0/pub-sub/subscriptions/${subId}/messages`; pollTimer = setInterval(async () => { try { const response = await fetch(pollUrl, { method: 'GET', headers: headers, signal: AbortSignal.timeout(30000) // 30秒超时避免请求挂起 }); if (!response.ok) { if (response.status === 404) { console.log("订阅已失效,重新创建订阅"); clearInterval(pollTimer); initSubscription(session); } return; } const messageData = await response.json(); if (messageData.messages?.length) { // 追加新事件到列表 setReceivedEvents(prev => [...prev, ...messageData.messages]); } } catch (err) { console.log('拉取消息出错:', err); } }, 5000); // 每5秒轮询一次,可根据业务调整间隔 } return ( <View style={{flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20}}> <Text style={{fontSize: 18, marginBottom: 10}}>已订阅事件: {eventName}</Text> <Text>累计接收事件: {receivedEvents.length}</Text> {receivedEvents.map((evt, idx) => ( <Text key={idx} style={{marginTop: 8, fontSize: 12}}> {JSON.stringify(evt.payload)} </Text> ))} </View> ); } export default History;
关键注意事项
- 权限配置:确保Salesforce用户已分配
PubSubAPI权限集,且对目标Platform Event拥有读权限 - API版本适配:使用支持Pub/Sub API的版本(v53.0及以上),建议使用最新稳定版
- 轮询优化:可根据业务需求调整轮询间隔,也可使用长轮询模式(设置
wait参数)减少请求次数 - 错误处理:需处理订阅失效、网络异常等场景,避免应用静默崩溃
内容的提问来源于stack exchange,提问作者Fırat DİKMEN
相关产品推荐
相关产品推荐

