React Native中Firestore无网络时未触发错误捕获问题求助
解决Firestore离线删除操作Promise无响应的问题
嘿,我之前也碰到过类似的情况,帮你梳理下问题根源和解决办法:
首先,虽然你禁用了Firestore的离线持久化,但Firestore客户端SDK的默认行为是——即使离线,写操作(包括删除)会被放入内存队列,它不会立刻拒绝请求,也不会马上resolve,会一直等网络恢复后再尝试同步。这就是为什么你的then和catch都没触发的原因——Promise一直处于pending状态。
下面给你几个可行的解决方案:
方案1:先检查网络状态再执行删除
最直接的办法就是在发起删除请求前,先判断设备是否联网,离线时直接给用户提示。可以用@react-native-community/netinfo来检测:
import NetInfo from '@react-native-community/netinfo'; // 先获取网络状态 NetInfo.fetch().then(state => { if (state.isConnected) { // 联网状态下执行删除 firebase.firestore().collection('d').doc(deviceid).delete() .then(() => { console.log("Device Deleted"); that.setState({ loading: false }); Toast.show('Device Deleted Succesfully', { duration: Toast.durations.SHORT, position: Toast.positions.TOP, shadow: true, animation: true, hideOnPress: true, delay: 0, }); }) .catch(err => { console.log(err); that.setState({ loading: false }); }); } else { // 离线时直接提示用户 that.setState({ loading: false }); Toast.show('No internet connection, please try again later', { duration: Toast.durations.SHORT, position: Toast.positions.TOP, }); } });
方案2:确保Firestore初始化配置正确
有时候react-native-firebase的Firestore SDK需要明确的配置才能彻底禁用离线相关的队列行为。初始化时可以加上这些设置:
import firebase from '@react-native-firebase/app'; import firestore from '@react-native-firebase/firestore'; firebase.initializeApp(); // 初始化Firestore时禁用持久化,加上额外配置 firestore().settings({ enablePersistence: false, experimentalForceLongPolling: true, // 针对RN环境的适配配置 });
方案3:给删除操作加超时机制
如果你希望即使离线时也能让Promise有响应,可以给删除操作设置超时,避免一直pending:
// 封装一个带超时的删除函数 const deleteWithTimeout = (docRef, timeoutMs = 5000) => { return Promise.race([ docRef.delete(), new Promise((_, reject) => { setTimeout(() => reject(new Error('Request timed out - check your internet connection')), timeoutMs); }) ]); }; // 使用这个函数执行删除 deleteWithTimeout(firebase.firestore().collection('d').doc(deviceid)) .then(() => { console.log("Device Deleted"); that.setState({ loading: false }); Toast.show('Device Deleted Succesfully', { duration: Toast.durations.SHORT, position: Toast.positions.TOP, shadow: true, animation: true, hideOnPress: true, delay: 0, }); }) .catch(err => { console.log(err); that.setState({ loading: false }); Toast.show(err.message, { duration: Toast.durations.SHORT, position: Toast.positions.TOP, }); });
补充说明
Firestore的SDK是为离线优先设计的,哪怕你关了持久化,它还是会在内存里暂存写请求,等网络回来再同步。这种设计导致离线时的写Promise不会有任何状态变化,一直挂着。所以要么提前拦截离线情况,要么给Promise加超时,确保你的UI能及时给用户反馈。
内容的提问来源于stack exchange,提问作者Honney Goyal
相关产品推荐
相关产品推荐

