Мы используем Firebase Authentication для анонимной аутентификации пользователей, когда они начинают свой первый сеанс. Позже они могут выбрать, чтобы войти в не анонимный поставщик. Мы используем библиотеку FirebaseUI, чтобы помочь с этим. Библиотека FirebaseUI имеет функцию автоанонимного обновления ( docs ), которую мы используем, чтобы упростить это для нас.
Документы описывают несколько крайних случаев, которые мы должны обработать, включая объединение аккаунтов сценарий, когда пользователь входит в существующую учетную запись. Когда это происходит, мы хотим перенести пользовательские данные (в Firestore), связанные с анонимной учетной записью, в существующую учетную запись и, наконец, войти в существующую учетную запись. Этот последний шаг автоматически и неизбежно отбрасывает анонимную учетную запись на клиенте, поэтому мы не можем вернуться к ней.
Логически этот процесс слияния не очень сложен. Единственная сложность состоит в том, чтобы сделать этот процесс настолько гибким, насколько это возможно, атомным c, чтобы пользователь не мог застрять в каком-то «неопределенном» состоянии.
Есть две точки отказа. Первый - когда мы переносим пользовательские данные, а второй - когда мы входим в существующую учетную запись. Наша идея достичь атомарности - начать миграцию до того, как пользователь войдет в существующую учетную запись, кэшировать данные в транзакции, которую можно отменить, а затем «зафиксировать» миграцию после успешного входа. Таким образом, мы сможем прервать слияние в случае сбоя переноса данных, а также при сбое входа.
Мой вопрос: если Auth.auth().signIn
возвращает ошибку, анонимная учетная запись гарантированно не была удалена? Другими словами: если вход не выполнен, можем ли мы продолжать использовать текущего анонимного пользователя или Auth SDK отбросил анонимного пользователя во время его попытки войти?
Ниже приведен скелет функции делегата FirebaseUI iOS / Swift, где я указал события миграции. Мы также открыты для предложений, выходящих за рамки нашего основного вопроса. Мы знаем, что мы не первые, кто реализовал эту идею, но документы / примеры не настолько глубоки go.
func authUI(_ authUI: FUIAuth, didSignInWith authDataResult: AuthDataResult?, error: Error?) {
if let error = error as NSError?, error.code == FUIAuthErrorCode.mergeConflict.rawValue {
// Merge conflict error, discard the anonymous user and login as the existing non-anonymous user.
guard let credential = error.userInfo[FUIAuthCredentialKey] as? AuthCredential else {
print("Received merge conflict error without auth credential!")
return
}
// Start migration process
Auth.auth().signIn(with: credential) { (dataResult, error) in
if let error = error as NSError? {
print("Failed to re-login: \(error)")
// Cancel migration process
// WE NEED TO REVERT TO THE ANONYMOUS USER!
return
}
// Finalize migration process
}
}
else if let error = error {
// Some non-merge conflict error happened.
print("Failed to log in: \(error)")
return
}
// Handle successful login
}