Firebase v9 Firebase Auth Gooleログインにてrouter.push(next/router)でのリダイレクトができない現象
SigninWIthRedirectだとPromiseの処理がresolvedされずにtryやthenの中身が実行できない
エラーでの終了もしないのでresolveされずにreject状態となりデプロイ時にUnhandledPromiseRejectionWarningエラーがでる
export const googleLogin = async () => {
await signInWithRedirect(auth, provider)
.then(() => {
console.log('google resolved')
Router.push('/community');
})
.catch((e: any) => {
alert(e.message);
});
};
一応、signInWithPopupに変えたらできるようになった
signInWithRedirectはサーバーサイドでの処理も必要だから?よくわかってない・・・
export const googleLogin = async () => {
await signInWithPopup(auth, provider)
.then(() => {
console.log('google resolved')
Router.push('/community');
})
.catch((e: any) => {
alert(e.message);
});
};
一応WA的なものも載せておく
元の画面でuserの状態を評価して、遷移させる
ただこれだと上記のように同じ関数内で実行されているわけではないのでタイムラグが生じて若干気持ち悪い
useEffect(() => {
user && router.push('/community');
setShow(false)
}, [router, user, setShow]);
※setShowはモーダルの表示/非表示
これで関数の実行によって遷移はするようになったが、ビルド時のエラーは解決できないのでもう一度原因を整理する。
なお、rejectで返されたPromiseオブジェクトをメソッドチェーンでもtry-catchでも受け取らなかった場合は、UnhandledPromiseRejectionWarningが発生しプロセスが終了するので、注意が必要です。
https://cyzennt.co.jp/blog/2021/09/21/javascript:async・awaitの例外処理/
これによるとそもそもrejectになっている?
でもthen()内の処理は実行されてるよ?
catch()が実行されていないからrejectは起きていないはず。
おそらく他が原因で起きている?
rejectで返されたPromiseオブジェクトはtry-catchで受け取ることも可能です。
ただし、この場合、戻り値を参照しないように注意が必要で、参照してしまうとUnhandledPromiseRejectionWarningが発生しプロセスが終了してしまいます。
これは知らなかった。
以下サンプルコード
⑤でconsole.logで戻り値を参照している部分をコメントアウト外すとエラーが出る
function lightTask() {
console.log("light");
}
function heavyTask() {
// awaitで呼び出される関数ではpromiseオブジェクトを返す必要がある
return new Promise((resolve, reject) => {
const procedure = () => {
console.log("heavy");
reject(1);
}
setTimeout(procedure, 1000);
});
}
// awaitを使用する関数にはasyncをつける
async function exection() {
try {
let result = await heavyTask();
console.log("code:"+result);
} catch (e) {
console.error("error:"+e);
// console.log("code:"+result); // ⑤
}
lightTask();
}
exection();
onclickのメソッドも一応Promise型になっていたので.catchで受け取るように変更してみる
変更前
const handleGoogleLogin = (): Promise<void> =>
googleLogin().catch((e) => {
});
変更後
const handleGoogleLogin = (): Promise<void> =>
googleLogin().catch((e) => {
console.log(e.message);
});
上はダメだったけどconsole.logをalertに変えたらエラーが消えた!なぜ?
const handleGoogleLogin = (): Promise<void> =>
googleLogin().catch((e) => {
alert(e.message);
});
このドキュメントも読んでおく