Javascript 如何在React Native中使用带BackgroundTimer的PubNub

Javascript 如何在React Native中使用带BackgroundTimer的PubNub,javascript,react-native,pubnub,Javascript,React Native,Pubnub,我正在尝试在React本机应用程序中实现PubNub。其想法是在后台运行PubNub,以便每隔30秒在特定频道中更新用户的位置 这是我的密码。这是my App.js中的导出默认功能: export default function ponte() { const [isLoading, setIsLoading] = React.useState(false); const [user, setUser] = React.useState(null); const [voluntee

我正在尝试在React本机应用程序中实现PubNub。其想法是在后台运行PubNub,以便每隔30秒在特定频道中更新用户的位置

这是我的密码。这是my App.js中的导出默认功能:

export default function ponte() {
  const [isLoading, setIsLoading] = React.useState(false);
  const [user, setUser] = React.useState(null);
  const [volunteerChannel, setVolunteerChannel] = React.useState(null);

  // Handle user state changes
  function onAuthStateChanged(user) {
    setUser(user);
    if (isLoading) setIsLoading(false);
  }

  if (isLoading) return null;

  useEffect(() => {
    SplashScreen.hide();
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber; // unsubscribe on unmount
  }, []);

  const authContext = React.useMemo(() => {
    return {
      signIn: (email, password) =>
        auth()
          .signInWithEmailAndPassword(email.email, password.password)
          .then(res => {
            setIsLoading(false);
            setUser(res.user.uid);
      })
    ,
      signUp: () => {
        setIsLoading(false);
        setUser("test");
      },
      signOut: () => {
        setIsLoading(false);
        auth().signOut().then(() => console.log('User signed out!'));
        setUser(null);
      }
    };
  }, []);
  
  BackgroundTimer.start();
  BackgroundTimer.runBackgroundTimer(() => {

    if(auth().currentUser && auth().currentUser.email /*&& !volunteerChannel*/) {
        Promise.all([
          fetch(API_URL + "/users?email=" + auth().currentUser.email)
      ])
      .then(([res1]) => Promise.all([res1.json()]))
        .then(([data1]) => { 
          if(data1[0].category === 'Voluntario') {
            console.log('Volunteer channel: ' + data1[0].email);

            GetLocation.getCurrentPosition({
              enableHighAccuracy: true,
              timeout: 15000,
            })
            .then(location => {
                var pubnub = new PubNubReact({
                  publishKey: 'xxxx',
                  subscribeKey: 'xxxx'
                });
                pubnub.publish({
                  message: {
                    latitude: location.latitude,
                    longitude: location.longitude
                  },
                  channel: data1[0].email
                });
            })
            .catch(error => {
                const { code, message } = error;
                console.warn(code, message);
            })
          } else {
            console.log(data1[0]);
          }
        })
        .catch((error) => console.log(error))
    } 
  }, 30000);

  BackgroundTimer.stop();

  return(
    <AuthContext.Provider value={authContext}>
      <NavigationContainer>
        <RootStackScreen user={user} />
      </NavigationContainer>
    </AuthContext.Provider>
  );

}
导出默认函数ponte(){
const[isLoading,setIsLoading]=React.useState(false);
const[user,setUser]=React.useState(null);
const[autonovateChannel,setAutonovateChannel]=React.useState(null);
//处理用户状态更改
函数onAuthStateChanged(用户){
setUser(用户);
如果(isLoading)设置isLoading(false);
}
if(isload)返回null;
useffect(()=>{
SplashScreen.hide();
const subscriber=auth().onAuthStateChanged(onAuthStateChanged);
返回订阅服务器;//卸载时取消订阅
}, []);
const authContext=React.useMoom(()=>{
返回{
登录:(电子邮件、密码)=>
auth()
.Signin with email and password(email.email,password.password)
。然后(res=>{
设置加载(假);
setUser(res.user.uid);
})
,
注册:()=>{
设置加载(假);
设置用户(“测试”);
},
注销:()=>{
设置加载(假);
auth().signOut().then(()=>console.log('User signed out!'));
setUser(空);
}
};
}, []);
BackgroundTimer.start();
BackgroundTimer.runBackgroundTimer(()=>{
if(auth().currentUser&&auth().currentUser.email/*&&&!志愿者频道*/){
我保证([
获取(API_URL+”/users?email=“+auth().currentUser.email)
])
.then(([res1])=>Promise.all([res1.json()]))
。然后(([data1])=>{
如果(数据1[0]。类别=='Voluntario'){
console.log('志愿者频道:'+data1[0]。电子邮件);
GetLocation.getCurrentPosition({
EnableHighAccurance:正确,
超时:15000,
})
。然后(位置=>{
var pubnub=新的PubNubReact({
publishKey:'xxxx',
订阅键:“xxxx”
});
发布({
信息:{
纬度:位置。纬度,
经度:location.longitude
},
频道:data1[0]。电子邮件
});
})
.catch(错误=>{
常量{代码,消息}=错误;
控制台。警告(代码、消息);
})
}否则{
console.log(data1[0]);
}
})
.catch((错误)=>console.log(错误))
} 
}, 30000);
BackgroundTimer.stop();
返回(
);
}
我担心这段代码有两件事:

  • 第一个是注册的pubnub交易量:显然我有超过3.5K的交易,而且我几乎没有在iOS模拟器中使用该应用程序

  • 第二个是我得到一个警告:
    取消了位置,被另一个请求取消了
    。我不太确定它是从哪里来的,可能是从GetLocation.getCurrentPosition来的,所以它可能与PubNub无关

所以我的问题是:我在React Native中使用PubNub的方法是否正确?如果没有,我该怎么做才能让它更好?

当你说“后台”时,你是指应用程序处于活动状态时的后台线程,还是指应用程序中的后台线程在设备上不处于活动状态?如果是前者,那么您只需要确保pubnub实例和侦听器仍然在作用域中。如果你指的是iOS后台应用程序,那么你必须拥有苹果(批准)和用户的权限。被另一个请求取消的位置听起来像是你的应用程序发出的自定义消息,但也可能是当应用程序进入后台时(或线程无法在你活动应用程序的后台运行)它正在失去与PubNub的连接(顺便说一句,这不是PubNub的错)。这只是一个应用程序告诉你发生了什么。如果您更改订阅的频道列表,也可能导致出现该消息,因为必须重新建立订阅连接,并且旧连接将被删除,以支持新连接。@CraigConover我可以在应用程序处于活动状态时将其作为后台线程运行,这就是我在这里尝试的操作。我的方法行吗?如果没有,是否有任何链接可以作为示例?您是否尝试过在后台线程中运行pubnub instance/addListener/subscribe。它应该会起作用。JS是异步的。@CraigConover是否直接在我的导出默认函数Ponte中而没有后台计时器?好的,我试试看。对不起,我知识贫乏。