"too much recursion" 同时通过 setInterval 和 getData 将 params(setData) 更新到 Firebase RTDB

"too much recursion" while updating params(setData) into Firebase RTDB through setInterval and getData

我是 React Native 的新手。我在将每个用户(成员)的数据(纬度、经度、时间戳)实时更新到 Firebase 数据库时遇到问题,出现无限循环

我的错误是“递归太多”

firebase.config.ts

const firebaseConfig = {
    ...
};

export const getCurrentLocation = (phoneNumber: number, setData: (locationParams: any) => void) => {
    const db = getDatabase();
    const reference = ref(db, 'members/' + phoneNumber);
    onValue(reference, (snapshot) => {
        const data = snapshot.val();
        setData(data);
    })
};


export const setCurrentLocation = (phoneNumber: number, latitude: number, longitude: number, timestamp: number) => {
    const db = getDatabase();
    const reference = ref(db, 'members/' + phoneNumber);
    set(reference, {
        latitude: latitude,
        longitude: longitude,
        timestamp: timestamp,
    }).then(() => console.log('setCurrentLocation to mainUser/firebase.config'));
};
const app = initializeApp(firebaseConfig);



memberList.tsx

const [userPhoneNumber, setUserPhoneNumber] = useState('0');
const members = useSelector((state: any) => state.members);

//get user's phoneNumber
const auth = getAuth();
    useEffect( ()=> {
        onAuthStateChanged(auth, (user) => {
            if (user) {
                setUserPhoneNumber(user.email.replace(/\D/gi, '') || '');
            } else {
                console.log('logged out')
            }
        });
    }, [])


useEffect(() => {
        const timer = setInterval( () => {
            
            members.map(function (el) {
                getCurrentLocation(el.phoneNumber, (locationParams: any) => {
                    let timestamp = new Date().getTime()/1000;
              
                    setCurrentLocation(el.phoneNumber, locationParams.latitude, locationParams.longitude, timestamp)
                })
            })
        }, 10000);

        return () => clearInterval(timer);
    }, []);

这看起来不对:

const timer = setInterval( () => {
    
    members.map(function (el) {
        getCurrentLocation(el.phoneNumber, (locationParams: any) => {
            let timestamp = new Date().getTime()/1000;
      
            setCurrentLocation(el.phoneNumber, locationParams.latitude, locationParams.longitude, timestamp)
        })
    })
}, 10000);

由于您的 getCurrentLocation 使用 onValue 附加了一个侦听器,只需为每个用户执行一次将立即执行您的 setData 调用以获取数据库中的当前值,每当该用户的数据更新时再次。将 onValue 与间隔计时器结合使用是 Firebase 中的反模式,当数据更改时,数据库已经回调到您的代码。现在,您每秒为每个用户附加一个新的侦听器,因此,如果在超过几秒后对用户数据进行更新,您的回调(和 setData)将被调用的频率超过必要的方式。

在 Firebase 中,附加您的侦听器一次(通常在页面加载时)并让它们继续工作,直到页面被卸载(或需要对侦听器进行其他更改)。

因此,如果您从代码中删除 setInterval,您应该会得到更好的结果。