Firebase UI - отличный инструмент для создания системы аутентификации пользователей! После того, как вы установите и настроите его правильно (как в вашем коде, так и в консоли Firebase), вы получите 11 красивых и рабочих пользовательских интерфейсов для автоматического входа в систему, для пользователей GCP (Google Cloud Platform) у вас даже будет еще два способа включить SAML и Провайдеры OIDC.

Установить и настроить

Начать не так уж и сложно, вы можете следовать документации по установке, включить конкретного провайдера в консоли Firebase и настроить. И поскольку я использую его для своего приложения Gatsby (это фреймворк, написанный на React), я также использую эту документацию для настройки в React.

Есть два компонента, которые вы можете использовать FirebaseUI: FirebaseAuth и StyledFirebaseAuth. Разница проиллюстрирована здесь в документации:

FirebaseAuth имеет ссылку на файл CSS FirebaseUI (это requires CSS).

StyledFirebaseAuth напрямую связан с CSS.

Пользуюсь последним. А вот базовый пример StyledFirebaseAuth из документации:

// Import FirebaseAuth and firebase.
import React from 'react';
import StyledFirebaseAuth from 'react-firebaseui/StyledFirebaseAuth';
import firebase from 'firebase';
// Configure Firebase.
const config = {
  apiKey: 'AIzaSyAeue-AsYu76MMQlTOM-KlbYBlusW9c1FM',
  authDomain: 'myproject-1234.firebaseapp.com',
  // ...
};
firebase.initializeApp(config);
// Configure FirebaseUI.
const uiConfig = {
  // Popup signin flow rather than redirect flow.
  signInFlow: 'popup',
  // Redirect to /signedIn after sign in is successful. Alternatively you can provide a callbacks.signInSuccess function.
  signInSuccessUrl: '/signedIn',
  // We will display Google and Facebook as auth providers.
  signInOptions: [
    firebase.auth.GoogleAuthProvider.PROVIDER_ID,
    firebase.auth.FacebookAuthProvider.PROVIDER_ID
  ]
};
class SignInScreen extends React.Component {
  render() {
    return (
      <div>
        <h1>My App</h1>
        <p>Please sign-in:</p>
        <StyledFirebaseAuth uiConfig={uiConfig} firebaseAuth={firebase.auth()}/>
      </div>
    );
  }
}

Обратный звонок после входа в систему

Документация очень ясна, поэтому я не планировал много говорить об этом. Больше всего меня волнует поток данных, потому что, когда я использовал его несколько дней назад в своем приложении Gatsby, я не видел слишком много информации. Поэтому я хочу записать это на случай, если кому-то это понадобится в будущем.

Когда он настроен, вы можете войти в систему с поставщиком, подключить его к Firestore и создать пользователя в Authentication в Firestore. После этого signInSuccessUrl: ‘/signedIn’ собирается перенаправить поток на /signedIn.

Но что, если вы хотите сделать больше, чем просто перенаправление? Затем вы должны использовать обратный вызов: signInSuccessWithAuthResult. Он должен быть вложен в callbacks объект в uiConfig. Итак, пример в документации выглядит так:

// Configure FirebaseUI.
  uiConfig = {
    // Popup signin flow rather than redirect flow.
    signInFlow: 'popup',
    // We will display Google and Facebook as auth providers.
    signInOptions: [
      firebase.auth.GoogleAuthProvider.PROVIDER_ID,
      firebase.auth.FacebookAuthProvider.PROVIDER_ID
    ],
    callbacks: {
      signInSuccessWithAuthResult: () => false
    }
  }

Используйте обратный вызов signInSuccessWithAuthResult, чтобы решить перенаправить или остаться

Обратный вызов будет функцией, которая принимает два параметра: authObject (обычно user) и redirectURL. Таким образом, вы можете делать больше после успешного входа в систему.

На самом деле он вернет простое boolean значение. Если он вернет true, то после входа пользователь будет перенаправлен на URL-адрес, указанный в signInSuccessUrl. Когда он вернет false, пользователь останется на той же странице.

Позаботьтесь об асинхронном запросе в signInSuccessWithAuthResult

Другая проблема, с которой я сталкиваюсь, когда играю с signInSuccessWithAuthResult, заключается в том, что, поскольку он запрашивает точное значение boolean, когда я использую async/await, чтобы попытаться получить данные из базы данных или API, я получил сообщение об ошибке, в котором говорилось, что я возвращаю Promise<boolean>, что делает не совсем соответствует тому, что signInSuccessWithAuthResult ожидает получить.

Чтобы справиться с этой проблемой, просто используйте очень маленький трюк: используйте .then для обработки обещания внутри функции. Это всего лишь небольшая уловка, но я не вижу слишком много информации о ней в Интернете, поэтому пишу ее здесь. Надеюсь, когда-нибудь это поможет тебе.

Примечания

Просто попробуйте поделиться заметкой о signInFlow. Есть два способа: popup и redirect. По умолчанию это redirect, поэтому, если вы хотите ускорить процесс загрузки, укажите popup!

Спасибо за прочтение!