Closed8

Firebase v9 Firebase Auth Gooleログインにてrouter.push(next/router)でのリダイレクトができない現象

CaaaaatsCaaaaats

SigninWIthRedirectだとPromiseの処理がresolvedされずにtryやthenの中身が実行できない
エラーでの終了もしないのでresolveされずにreject状態となりデプロイ時にUnhandledPromiseRejectionWarningエラーがでる
https://github.com/hirooutdoor/penn/issues/111

export const googleLogin = async () => {
  await signInWithRedirect(auth, provider)
    .then(() => {
      console.log('google resolved')
      Router.push('/community');
    })
    .catch((e: any) => {
      alert(e.message);
    });
};
CaaaaatsCaaaaats

一応、signInWithPopupに変えたらできるようになった
signInWithRedirectはサーバーサイドでの処理も必要だから?よくわかってない・・・


export const googleLogin = async () => {
  await signInWithPopup(auth, provider)
    .then(() => {
      console.log('google resolved')
      Router.push('/community');
    })
    .catch((e: any) => {
      alert(e.message);
    });
};
CaaaaatsCaaaaats

一応WA的なものも載せておく
元の画面でuserの状態を評価して、遷移させる
ただこれだと上記のように同じ関数内で実行されているわけではないのでタイムラグが生じて若干気持ち悪い

  useEffect(() => {
    user && router.push('/community');
    setShow(false)
  }, [router, user, setShow]);

※setShowはモーダルの表示/非表示

CaaaaatsCaaaaats

これで関数の実行によって遷移はするようになったが、ビルド時のエラーは解決できないのでもう一度原因を整理する。

なお、rejectで返されたPromiseオブジェクトをメソッドチェーンでもtry-catchでも受け取らなかった場合は、UnhandledPromiseRejectionWarningが発生しプロセスが終了するので、注意が必要です。
https://cyzennt.co.jp/blog/2021/09/21/javascript:async・awaitの例外処理/

これによるとそもそもrejectになっている?
でもthen()内の処理は実行されてるよ?
catch()が実行されていないからrejectは起きていないはず。
おそらく他が原因で起きている?

CaaaaatsCaaaaats

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();
CaaaaatsCaaaaats

onclickのメソッドも一応Promise型になっていたので.catchで受け取るように変更してみる
変更前

  const handleGoogleLogin = (): Promise<void> =>
    googleLogin().catch((e) => {
    });

変更後

  const handleGoogleLogin = (): Promise<void> =>
    googleLogin().catch((e) => {
      console.log(e.message);
    });
CaaaaatsCaaaaats

上はダメだったけどconsole.logをalertに変えたらエラーが消えた!なぜ?

  const handleGoogleLogin = (): Promise<void> =>
    googleLogin().catch((e) => {
     alert(e.message);
    });
このスクラップは2021/11/06にクローズされました