문제
앱을 테스트하는데 앱을 딱 처음 받아서 실행할 때, 항상 에러가 한번 나고 그 후로는 에러가 안났다.
이전의 디버깅들로 쌓인 경험상 왠지 또 deviceToken이 안들어가고 있는 것 같았다
디버깅 해보니 역시나 아래와 같이 deviceToken이 들어가지 않은 요청이 보내지고 있었다.
처음에 deviceToken을 받고 나서는 asyncstorage에 저장되니까 한번 실패한 다음부터는 에러가 나지 않는 걸로 예상된다.
아래는 현재 코드이다. 메인함수에서 미리 정의된 useFCMToken이라는 hook을 이용하여 fcmToken을 불러온 후, sendImages에서 사용한다.
function App() {
const fcmToken = useFCMToken();
...
React.useEffect(() => {
const getPermissionAndSendImages = async () => {
...
// 사진 서버로 전송하는 코드
};
getPermissionAndSendImages();
}, []);
const sendImages = async newImages => {
const formData = getFormDataWithImageResize(newImages);
const config = {
headers: {
'Content-Type': 'multipart/form-data',
userDeviceToken: fcmToken,
},
};
customAxios
.post('/images', formData, config)
.then(data => {
console.log('MY LOGGG : /images SEND IMAGES SUCCESS : ', data);
if (imageListNum == sendImageListNum + 1) {
saveImages(allImages); // 전송한 캡쳐사진 저장
setDataLoadState(3);
}
sendImageListNum += 1;
})
.catch(err => {
setDataLoadState(4);
});
};
아래는 useFCMToken.js이다.
export const useFCMToken = () => {
const [token, setToken] = useState(null);
useEffect(() => {
const getFCMToken = async () => {
let fcmToken = await AsyncStorage.getItem('fcmToken');
if (!fcmToken) {
try {
fcmToken = await messaging().getToken();
if (fcmToken) {
await AsyncStorage.setItem('fcmToken', fcmToken);
}
} catch (err) {
console.log(err, 'fcmtoken에서 error 발생');
}
}
setToken(fcmToken);
};
getFCMToken();
}, []);
return token;
};
해결방법
fcmToken이 준비되지 않았음에도 독립적으로 수행되는 것을 막기 위해 아래와 같이
isTokenReady라는 state를 만들었다.
export const useFCMToken = () => {
const [token, setToken] = useState(null);
const [isTokenReady, setIsTokenReady] = useState(false);
useEffect(() => {
const getFCMToken = async () => {
let fcmToken = await AsyncStorage.getItem('fcmToken');
if (!fcmToken) {
try {
fcmToken = await messaging().getToken();
if (fcmToken) {
await AsyncStorage.setItem('fcmToken', fcmToken);
setIsTokenReady(true)
}
} catch (err) {
console.log(err, 'fcmtoken에서 error 발생');
}
}
setToken(fcmToken);
setIsTokenReady(true)
};
getFCMToken();
}, []);
return {token, isTokenReady};
};
그리고 App.js에서 hook으로 부터 받은 isTokenReady를 확인하여 true일 때 기존의 로직을 수행하도록 한다.
const getPermissionAndSendImages = async () => {
const permission = await getStoragePermission();
if (!permission) {
setDataLoadState(4);
return;
}
setDataLoadState(1);
allImages = await readImages(); // 기기의 모든 캡쳐사진 가져오기
newImages = await checkNewImages(allImages); // 새로운 캡쳐사진만 가져오기
if (newImages.length == 0) {
setDataLoadState(3);
}
const sliceLists = sliceImageList(newImages); // -> newImages 사진 배열 여러개로 나누기
imageListNum = sliceLists.length;
// 50개씩 잘라서 서버에 전송
sliceLists.forEach(async newImages => {
sendImages(newImages);
});
};
React.useEffect(() => {
if (isTokenReady) getPermissionAndSendImages();
}, [isTokenReady]);
이렇게 하니까 fcmToken이 null로 들어가는 일이 없어졌다!
끝!
'코딩일지' 카테고리의 다른 글
[2023-06-12] 키보드에 따라 사진이 같이 올라가는 문제 해결 (1) | 2023.06.12 |
---|---|
[2023-06-07] 이미지태거 release 모드에서 실행안되는 오류 (0) | 2023.06.07 |
[2023-06-06] 이미지태거 오류 수정 (0) | 2023.06.06 |
[2023-06-06] 이미지태거 리팩토링 - 크기가 큰 배열 나누어서 전송하기 (0) | 2023.06.06 |
[2023-06-05] 보낸 이미지 저장해서 같은 이미지 전송되지 않도록 하기 (0) | 2023.06.05 |