"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
,您应该会得到更好的结果。
我是 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
,您应该会得到更好的结果。