Обновите документ с новым идентификатором пользователя после повторной аутентификации пользователя - PullRequest
0 голосов
/ 22 апреля 2019

У меня есть следующий вариант использования, который работает, как и ожидалось:

  1. новый пользователь заходит на сайт
  2. пользователь получает user.uid от анонимного входа из firebase
  3. пользователь создает документ, имеющий в качестве userId ссылку на вышеупомянутую user.uid
  4. на той же самой странице, на которую приглашается войти пользователь, в противном случае документ будет утерян
  5. пользователь входит в систему инаходит в этом аккаунте документ

WIN!

Теперь у меня есть сценарий использования, который не работает должным образом:

  1. возвращающийся пользователь с истекшим сеансом или из другого браузера прибывает на веб-сайт
  2. пользователь получает user.uid от анонимного входа из firebase
  3. пользователь создает документ, имеющий в качестве userId ссылку на вышеупомянутое user.uid
  4. на той же странице пользователю предлагается войти в систему, в противном случае документ будет утерян
  5. пользователь войдет в систему и не найдет в этом аккаунте документ

НЕ ВЫИГРАЛ В ЭТО ВРЕМЯ: (

Я настроил firebase auth со следующей конфигурацией:

const uiConfig = {
  signInFlow: 'popup',
  autoUpgradeAnonymousUsers: true,
  signInOptions: [
    firebase.auth.GoogleAuthProvider.PROVIDER_ID,
  ],
  callbacks: {
    signInFailure: (error: any) => {
      if (error.code != 'firebaseui/anonymous-upgrade-merge-conflict') {
        return Promise.resolve();
      }
      var cred = error.credential;
      return firebase.auth().SignInAndRetrieveDataWithCredential(cred);
    }

  },
};

Итак, как вы можете видеть, проблема в том, чтов первый раз autoUpgradeAnonymousUsers создайте новый идентификатор пользователя с анонимным идентификатором пользователя, и все в порядке, но, конечно, второй раз больше не работает.

Как мне решить эту проблему, учитывая это в моих правилах безопасностиЯ хочу создать проверку, что userId не может быть обновлено И документ может просматривать только запрос с тем же userId?

правила безопасности:

allow create: if request.auth.uid != null
allow read: if request.auth.uid == resource.data.userId 
                    && request.auth.uid != null
allow update: if request.auth.uid == request.resource.data.userId && resource.data.userId == request.resource.data.userId && request.auth.uid != null

Спасибо.

1 Ответ

0 голосов
/ 23 апреля 2019

Проблема в том, что вы не можете создать нового пользователя с такими же учетными данными.Если пользователь входит в систему, он теряет данные от анонимного входа.

Вы должны сохранить данные от анонимного пользователя локально, и после того, как пользователь войдет в систему, вы должны скопировать данные текущему пользователю.Вам также следует удалить анонимную учетную запись.

Я нашел этот пример, который использует базу данных Firebase в реальном времени для сохранения пользовательских данных.

https://github.com/firebase/firebaseui-web#upgrading-anonymous-users

    // signInFailure callback must be provided to handle merge conflicts which
    // occur when an existing credential is linked to an anonymous user.
    signInFailure: function(error) {
      // For merge conflicts, the error.code will be
      // 'firebaseui/anonymous-upgrade-merge-conflict'.
      if (error.code != 'firebaseui/anonymous-upgrade-merge-conflict') {
        return Promise.resolve();
      }
      // The credential the user tried to sign in with.
      var cred = error.credential;
      // If using Firebase Realtime Database. The anonymous user data has to be
      // copied to the non-anonymous user.
      var app = firebase.app();
      // Save anonymous user data first.
      return app.database().ref('users/' + firebase.auth().currentUser.uid)
          .once('value')
          .then(function(snapshot) {
            data = snapshot.val();
            // This will trigger onAuthStateChanged listener which
            // could trigger a redirect to another page.
            // Ensure the upgrade flow is not interrupted by that callback
            // and that this is given enough time to complete before
            // redirection.
            return firebase.auth().signInWithCredential(cred);
          })
          .then(function(user) {
            // Original Anonymous Auth instance now has the new user.
            return app.database().ref('users/' + user.uid).set(data);
          })
          .then(function() {
            // Delete anonymnous user.
            return anonymousUser.delete();
          }).then(function() {
            // Clear data in case a new user signs in, and the state change
            // triggers.
            data = null;
            // FirebaseUI will reset and the UI cleared when this promise
            // resolves.
            // signInSuccessWithAuthResult will not run. Successful sign-in
            // logic has to be run explicitly.
            window.location.assign('<url-to-redirect-to-on-success>');
          });

    }
...