Firestore Native Client SDK冷启动问题排查(React Native Firebase)
Firestore Client SDK 冷启动长耗时异常问题
我基于@react-native-firebase在Android和iOS应用中使用Firestore Client SDK,整体运行正常,但遇到了一个无法解释的异常:
我记录了从用户登录到从Firestore获取对应UID数据的耗时,正常情况下,基于onAuthStateChanged的流程耗时约0.4-0.6s,代码实现如下:
let userLoggedIn: Date; let userDataReceived: Date; auth().onAuthStateChanged(async (user) => { userLoggedIn = new Date(); const eventsRetrieved = async (data: UserInformation) => { userDataReceived = new Date(); getDataDuration = `Get data duration: ${( (userDataReceived.getTime() - userLoggedIn.getTime()) / 1000 ).toString()}s`; console.log(getDataDuration) // function to check user role and to advance timing logs onUserDataReceived(data); }; const errorRetrieved = () => { signOut(); authStateChanged(false); }; let unSub: (() => void) | undefined; if (user && user.uid) { const userListener = () => { return firestore() .collection('Users') .doc(user.uid) .onSnapshot((querySnapshot) => { if (querySnapshot && querySnapshot.exists) { const data = querySnapshot.data() as UserInformation; data.id = querySnapshot.id; eventsRetrieved(data); } else errorRetrieved(); }); }; unSub = userListener(); } else { if (typeof unSub === 'function') unSub(); authStateChanged(false); } });
但当应用间隔约30-50分钟(近期测试发现最短仅10分钟)再次打开时,获取数据的耗时会达到3-9s(甚至15s),而紧接着再次打开应用,耗时又恢复至0.4-0.6s。
该问题仅在打包后的应用中出现,本地开发环境无法复现,已持续数周。
已确认的关键点:
- 无论是使用
onSnapshot监听还是getDoc查询(已测试两种方式),都是针对单个文档的简单查询,仅在类似“冷启动”的时间间隔下出现长耗时; - Firestore规则不应是耗时原因,因为后续请求速度正常,规则伪代码如下:
function checkCustomer(){ let data = get(/databases/$(database)/documents/Users/$(request.auth.uid)).data; return (resource.data.customerID == data.customerID); } match /Users/{id}{ allow read:if checkUserRole() // Checks user is logged in and has certain customClaim && idComparison(request.auth.uid, id) // Checks user uid is same as document id && checkCustomer() // User can read user data only if data is under same customer } - 清理应用缓存后问题仍存在,说明与设备缓存无关;
- 该“冷启动”现象是设备独立的,其他设备的操作无法缓解当前设备的延迟,与Cloud Run的最小实例机制不同。
后续测试将listener替换为getDoc调用,打包应用中仍存在相同问题,代码如下:
await firestore() .collection('Users') .doc(user.uid) .get() .then(async document => { if (document.exists) { const data = document.data() as UserInformation; if (data) data.id = document.id; eventsRetrieved(data); } });
目前计划向Firebase bug报告团队反馈该问题。
内容的提问来源于stack exchange,提问作者Hessuew
相关产品推荐
相关产品推荐

