如何为Expo Camera的二维码扫描添加合理的扫描间隔?
解决Expo Camera重复扫描二维码触发多次认证请求的问题
问题分析
你的核心问题是相机持续识别同一二维码,导致onBarcodeScanned被频繁触发——即使加了延迟也只是推迟了请求执行,没有阻止相机的重复扫描检测。同时当前逻辑在认证失败后没有重置扫描状态,无法重新发起扫描。
解决方案
通过引入处理中状态来控制扫描触发时机,确保同一时间只有一个认证请求在处理,并且在认证失败后重置状态允许重新扫描:
修改后的代码
import React, { useState } from "react"; import { View, Text, TouchableOpacity, StyleSheet, Button, ActivityIndicator } from "react-native"; import { CameraView, useCameraPermissions } from "expo-camera"; import { auth } from "../../firebase/firebaseConfig"; import { signInWithCustomToken } from "firebase/auth"; const QRcodeScan = ({ navigation }) => { const [scanned, setScanned] = useState(false); // 新增状态:标记是否正在处理认证请求 const [isProcessing, setIsProcessing] = useState(false); const handleBarcodeScanned = async (scannedData) => { console.log("Scanned token:", scannedData); try { const userCredential = await signInWithCustomToken(auth, scannedData); console.log("Signed in successfully as:", userCredential.user.uid); navigation.navigate("ProfileSelection"); } catch (error) { console.error("Error signing in with custom token:", error); // 认证失败后,重置状态允许重新扫描 setScanned(false); setIsProcessing(false); } }; return ( <View style={styles.container}> <CameraView style={styles.camera} facing={facing} onBarcodeScanned={({ data }) => { // 只有当未扫描过、未在处理中且有有效数据时,才启动认证流程 if (data && !scanned && !isProcessing) { setScanned(true); setIsProcessing(true); handleBarcodeScanned(data); } }} > {/* 可选:添加加载提示,提升用户体验 */} {isProcessing && ( <View style={styles.loadingOverlay}> <ActivityIndicator size="large" color="#fff" /> <Text style={styles.loadingText}>正在验证...</Text> </View> )} {/* Rest of the code */} </CameraView> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", }, camera: { flex: 1, width: "100%", position: "relative", }, loadingOverlay: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, backgroundColor: "rgba(0,0,0,0.7)", justifyContent: "center", alignItems: "center", }, loadingText: { color: "#fff", marginTop: 16, fontSize: 16, }, }); export default QRcodeScan;
关键改动说明
- 新增
isProcessing状态:彻底阻止相机在认证请求未完成时重复触发扫描逻辑。 - 严格控制触发条件:只有当存在有效扫描数据、未扫描过且不在处理中时,才启动认证流程。
- 失败后重置状态:在
catch块中将scanned和isProcessing设为false,允许用户重新扫描。 - 移除不必要的
setTimeout:延迟无法阻止重复扫描,直接同步触发认证即可。
额外优化建议
- 可以对扫描到的
scannedData做短时间缓存,避免同一二维码被重复处理。 - 若二维码可能过期,可在认证失败时提示用户二维码无效或已过期。
内容的提问来源于stack exchange,提问作者Development DOEdeal
相关产品推荐
相关产品推荐

