簡體   English   中英

在創建 Firestore 文檔之前進行 FirebaseUI 身份驗證重定向

[英]FirebaseUI auth redirecting before Firestore document is created

設置:Vue.js、Vuetify、FirebaseUI、Firestore、Vue-router、Vue CLI

我的期望:Oauth 會成功,在 localStorage 中設置 userEmail,在users集合中創建一個 Firestore 文檔,然后頁面會重定向。

現實:宣誓成功,在localStorage中設置了userEmail,頁面重定向

我嘗試使用 async/await 無濟於事,從signInSuccessWithAuthResult返回任何內容,使用signInSuccessUrl進行重定向也不起作用。 window.location.href = "/"location.href.replace("/")也沒有改變任何東西。 如果我刪除重定向,則會創建文檔,這讓我相信重定向會中斷文檔創建。 我是 Firebase 的新手,但我不明白為什么這不起作用。 任何幫助將不勝感激,如果您需要更多詳細信息,請發表評論。

let ui = firebaseui.auth.AuthUI.getInstance();
    if (!ui) {
      ui = new firebaseui.auth.AuthUI(firebase.auth());
    }
    let uiConfig = {
      signInOptions: [
        firebase.auth.GoogleAuthProvider.PROVIDER_ID,
        firebase.auth.FacebookAuthProvider.PROVIDER_ID,
        firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID
      ],
      signInFlow: "popup",
      callbacks: {
        signInSuccessWithAuthResult: function(authResult) {
          let email = authResult.user.isAnonymous
            ? "guest"
            : authResult.user.email;
          localStorage.setItem("userEmail", email);
          if (
            authResult.additionalUserInfo.isNewUser &&
            !authResult.user.isAnonymous
          ) {
            db.collection("users")
              .add({
                email: authResult.user.email,
                expire: new firebase.firestore.Timestamp.now(),
                positions: [0, 0, 0],
                premium: false
              })
              .then(() => {
                window.location.pathname = "/";
              });
          }
          window.location.pathname = "/";
          return false;
        }
      }
    };
    ui.start("#firebaseui-auth-container", uiConfig);

我認為這里的流程有幾個問題,一個是關於異步如何工作的一般問題,另一個是 FirebaseUI 特有的。 我會涵蓋兩者。

首先讓我們看一下回調代碼的運行順序:

        signInSuccessWithAuthResult: function(authResult) {
// 1. BEGINS RUNNING HERE
          let email = authResult.user.isAnonymous
            ? "guest"
            : authResult.user.email;
          localStorage.setItem("userEmail", email);
          if (
            authResult.additionalUserInfo.isNewUser &&
            !authResult.user.isAnonymous
          ) {

// 2. THIS FUNCTION KICKS OFF BUT WILL RETURN IMMEDIATELY
            db.collection("users")
              .add({
                email: authResult.user.email,
                expire: new firebase.firestore.Timestamp.now(),
                positions: [0, 0, 0],
                premium: false
              })
              .then(() => {
// 4. THIS WOULD RUN LAST, BUT PROBABLY IS ABORTED/SKIPPED DUE TO 3
                window.location.pathname = "/";
              });
          }
// 3. THIS REDIRECT WILL BE TRIGGERED WHILE THE .add() IS EXECUTING async
          window.location.pathname = "/";
          return false;
        }
      }
    };

因此,要解決此問題,您需要在 3) 處刪除重定向,並且僅在保存集合后才重定向。

但! 回調返回時, FirebaseUI 會自動跳轉到“成功”頁面。 因此,即使您進行了上述更改,FirebaseUI 重定向也會隨機中止db.collection.add()並將頁面重新加載到默認的“/success”。

要停止這種情況,您必須使用 async/await 阻止回調的返回,並刪除您的手動重定向並配置成功 url。

    const uiConfig = {
      signInSuccessUrl: '/success',
      callbacks: {
        signInSuccessWithAuthResult: async function(authResult) {
            // ...
            await db.collection("users").add({ ... });
        }
      }
    };

async添加到回調允許您阻止並等待 db.collection.add 返回。 那么你不應該手動重定向,因為signInSuccessUrl會為你做,所以你會得到第二個競爭條件。

我在這里對其進行了簡化,因此請確保您不要添加任何其他非等待的異步任務,否則它們也會競爭。 (例如 LocalStorage.setItem() 正在阻塞,但如果您使用 AsyncStorage.setItem() ,您會遇到同樣的問題,也應該等待)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM