1. Прежде чем начать
В этом практическом занятии вы узнаете, как добавить аутентификацию Firebase в ваше Flutter-приложение с помощью пакета FlutterFire UI. С помощью этого пакета вы добавите в Flutter-приложение аутентификацию по электронной почте и паролю, а также аутентификацию через Google. Вы также узнаете, как настроить проект Firebase и использовать CLI FlutterFire для инициализации Firebase в вашем Flutter-приложении.
Предварительные требования
Данный практический пример предполагает наличие у вас некоторого опыта работы с Flutter. Если нет, возможно, вам стоит сначала изучить основы. Следующие ссылки могут быть полезны:
- Ознакомьтесь с фреймворком виджетов Flutter.
- Попробуйте выполнить задание «Напишите свое первое приложение Flutter, часть 1» на Codelab.
Вам также потребуется некоторый опыт работы с Firebase, но ничего страшного, если вы никогда не добавляли Firebase в проект Flutter. Если вы не знакомы с консолью Firebase или вообще ничего о Firebase не знаете, сначала ознакомьтесь со следующими ссылками:
Что вы создадите
В этом практическом занятии вы научитесь создавать процесс аутентификации для приложения Flutter, используя Firebase для аутентификации. Приложение будет включать экран входа в систему, экран регистрации, экран восстановления пароля и экран профиля пользователя.




Что вы узнаете
Данный практический семинар охватывает следующие темы:
- Добавление Firebase в приложение Flutter
- Настройка консоли Firebase
- Использование Firebase CLI для добавления Firebase в ваше приложение.
- Использование FlutterFire CLI для генерации конфигурации Firebase в Dart
- Добавление аутентификации Firebase в ваше Flutter-приложение
- Настройка аутентификации Firebase в консоли.
- Добавление входа по электронной почте и паролю с помощью пакета
firebase_ui_auth - Добавление регистрации пользователей с помощью пакета
firebase_ui_auth - Добавление страницы «Забыли пароль?»
- Добавление входа через Google с использованием
firebase_ui_auth - Настройка вашего приложения для работы с несколькими системами авторизации.
- Добавление экрана профиля пользователя в ваше приложение с помощью пакета
firebase_ui_auth
Данная практическая работа посвящена созданию надежной системы аутентификации с использованием пакета firebase_ui_auth . Как вы увидите, все это приложение со всеми вышеперечисленными функциями можно реализовать примерно за 100 строк кода.
Что вам понадобится
- Практические навыки работы с Flutter и установленным SDK.
- Текстовый редактор (Flutter поддерживает IDE от JetBrains, Android Studio и VS Code).
- Используйте браузер Google Chrome или другую предпочтительную среду разработки для Flutter. (Некоторые команды терминала в этом практическом руководстве предполагают, что ваше приложение запущено в Chrome).
2. Создайте и настройте проект Firebase.
Первым делом вам нужно будет создать проект Firebase в веб-консоли Firebase.
Создайте проект Firebase.
- Войдите в консоль Firebase, используя свою учетную запись Google.
- Нажмите кнопку, чтобы создать новый проект, а затем введите название проекта (например,
FlutterFire-UI-Codelab). - Нажмите «Продолжить» .
- Если появится запрос, ознакомьтесь с условиями использования Firebase и примите их, после чего нажмите «Продолжить» .
- (Необязательно) Включите помощь ИИ в консоли Firebase (в Firebase она называется "Gemini").
- Для этого практического занятия вам не понадобится Google Analytics, поэтому отключите эту опцию.
- Нажмите «Создать проект» , дождитесь завершения подготовки проекта, а затем нажмите «Продолжить» .
Чтобы узнать больше о проектах Firebase, см. раздел «Понимание проектов Firebase» .
Включите вход по электронной почте для аутентификации Firebase.
Создаваемое вами приложение использует Firebase Authentication для авторизации пользователей. Оно также позволяет новым пользователям регистрироваться прямо из приложения Flutter.
Аутентификацию Firebase необходимо включить через консоль Firebase, и после включения потребуется специальная настройка.
Чтобы пользователи могли входить в веб-приложение, сначала используйте вход по электронной почте и паролю . Позже добавьте вход через Google .
- В консоли Firebase разверните меню «Сборка» на левой панели.
- Нажмите «Аутентификация» , затем нажмите кнопку «Начать» , а затем вкладку «Способ входа» (или перейдите непосредственно на вкладку «Способ входа» ).
- В списке поставщиков услуг входа выберите «Электронная почта/Пароль» , установите переключатель «Включить» в положение «Вкл.», а затем нажмите «Сохранить» .

3. Настройка приложения Flutter
Перед началом работы вам потребуется загрузить стартовый код и установить Firebase CLI.
Получите стартовый код
Клонируйте репозиторий GitHub из командной строки:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
В качестве альтернативы, если у вас установлен инструмент командной строки GitHub :
gh repo clone flutter/codelabs flutter-codelabs
Пример кода следует клонировать в каталог flutter-codelabs на вашем компьютере, который содержит код для набора практических заданий. Код для этого практического задания находится в подкаталоге flutter-codelabs/firebase-auth-flutterfire-ui .
В директории flutter-codelabs/firebase-auth-flutterfire-ui находятся два проекта Flutter. Один называется complete , а другой — start . В директории start находится незавершенный проект, и именно там вы проведете большую часть времени.
cd flutter-codelabs/firebase-auth-flutterfire-ui/start
Если вы хотите перейти к следующему шагу или посмотреть, как должен выглядеть готовый результат, загляните в каталог с именем complete для получения перекрестной ссылки.
Если вы хотите следовать инструкциям в этом руководстве и добавлять код самостоятельно, начните с приложения Flutter по адресу flutter-codelabs/firebase-auth-flutterfire-ui/start и добавляйте код в этот проект на протяжении всего руководства. Откройте или импортируйте эту директорию в вашу предпочтительную IDE.
Установите Firebase CLI.
Firebase CLI предоставляет инструменты для управления вашими проектами Firebase. Этот CLI необходим для FlutterFire CLI, который вы установите чуть позже.
Существует несколько способов установки CLI. Ознакомьтесь со всеми доступными вариантами для вашей операционной системы на сайте firebase.google.com/docs/cli .
После установки CLI необходимо пройти аутентификацию в Firebase.
- Войдите в Firebase, используя свою учетную запись Google, выполнив следующую команду:
firebase login
- Эта команда подключает ваш локальный компьютер к Firebase и предоставляет вам доступ к вашим проектам Firebase.
- Проверьте правильность установки CLI и наличие у него доступа к вашей учетной записи, выведя список ваших проектов Firebase. Выполните следующую команду:
firebase projects:list
- Отображаемый список должен совпадать со списком проектов Firebase в консоли Firebase . Вы должны увидеть как минимум
flutterfire-ui-codelab.
Установите FlutterFire CLI.
FlutterFire CLI — это инструмент, упрощающий процесс установки Firebase на всех поддерживаемых платформах в вашем Flutter-приложении. Он построен на основе Firebase CLI.
Сначала установите интерфейс командной строки:
dart pub global activate flutterfire_cli
Убедитесь, что CLI установлен. Выполните следующую команду и проверьте, выводит ли CLI меню справки.
flutterfire --help
Добавьте свой проект Firebase в приложение Flutter.
Настройка FlutterFire
Вы можете использовать FlutterFire для генерации необходимого кода Dart для использования Firebase в вашем Flutter-приложении.
flutterfire configure
При выполнении этой команды вам будет предложено выбрать, какой проект Firebase вы хотите использовать и какие платформы вы хотите настроить.
На следующих скриншотах показаны вопросы, на которые вам нужно будет ответить.
- Выберите проект, который хотите использовать. В данном случае используйте
flutterfire-ui-codelab
- Выберите, какие платформы вы хотите использовать. В этом руководстве описаны шаги по настройке аутентификации Firebase для Flutter для веб-приложений, iOS и Android, но вы можете настроить свой проект Firebase для использования всех вариантов.

- На этом скриншоте показан результат в конце процесса. Если вы знакомы с Firebase, вы заметите, что вам не пришлось создавать приложения для платформы (например, приложение для Android) в консоли, это сделал за вас FlutterFire CLI.

После завершения процесса откройте приложение Flutter в текстовом редакторе. FlutterFire CLI изменил файл firebase_options.dart . Этот файл содержит класс FirebaseOptions , в котором есть статические переменные, хранящие конфигурацию Firebase, необходимую для каждой платформы. Если вы выбрали все платформы при запуске flutterfire configure , вы увидите статические значения с именами web , android , ios и macos .
lib/firebase_options.dart
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyCqFjCV_9CZmYeIvcK9FVy4drmKUlSaIWY',
appId: '1:963656261848:web:7219f7fca5fc70afb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
authDomain: 'flutterfire-ui-codelab.firebaseapp.com',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
measurementId: 'G-DGF0CP099H',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyDconZaCQpkxIJ5KQBF-3tEU0rxYsLkIe8',
appId: '1:963656261848:android:c939ccc86ab2dcdbb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
iosBundleId: 'com.example.complete',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
iosBundleId: 'com.example.complete',
);
}
В Firebase слово «приложение» используется для обозначения конкретной сборки для конкретной платформы в проекте Firebase. Например, проект Firebase под названием FlutterFire-ui-codelab содержит несколько приложений: одно для Android, одно для iOS, одно для macOS и одно для веб-версии.
Метод DefaultFirebaseOptions.currentPlatform использует перечисление TargetPlatform , предоставляемое Flutter, для определения платформы, на которой работает ваше приложение, а затем возвращает значения конфигурации Firebase, необходимые для соответствующего приложения Firebase.
Добавьте пакеты Firebase в приложение Flutter.
Последний шаг настройки — добавление соответствующих пакетов Firebase в ваш проект Flutter. В файле firebase_options.dart должны быть ошибки, поскольку он зависит от пакетов Firebase, которые еще не были добавлены. В терминале убедитесь, что вы находитесь в корневой директории проекта Flutter по адресу flutter-codelabs/firebase-emulator-suite/start . Затем установите три необходимых пакета, используя следующую команду:
flutter pub add firebase_core firebase_auth firebase_ui_auth
На данный момент вам понадобятся только эти пакеты.
Инициализация Firebase
Для использования добавленных пакетов и параметра DefaultFirebaseOptions.currentPlatform, обновите код в функции main в файле main.dart .
lib/main.dart
import 'package:firebase_core/firebase_core.dart'; // Add this import
import 'package:flutter/material.dart';
import 'app.dart';
import 'firebase_options.dart'; // And this import
// TODO(codelab user): Get API key
const clientId = 'YOUR_CLIENT_ID';
void main() async {
// Add from here...
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// To here.
runApp(const MyApp(clientId: clientId));
}
Этот код делает две вещи.
-
WidgetsFlutterBinding.ensureInitialized()указывает Flutter не запускать выполнение кода виджета приложения до тех пор, пока фреймворк Flutter не будет полностью загружен. Firebase использует нативные каналы платформы, для работы которых требуется запущенный фреймворк. -
Firebase.initializeAppустанавливает связь между вашим Flutter-приложением и проектом Firebase. ПараметрDefaultFirebaseOptions.currentPlatformимпортируется из сгенерированного файлаfirebase_options.dart. Это статическое значение определяет, на какой платформе вы работаете, и передает соответствующие ключи Firebase.
4. Добавьте начальную страницу аутентификации Firebase UI.
Firebase UI for Auth предоставляет виджеты, которые представляют собой целые экраны вашего приложения. Эти экраны обрабатывают различные потоки аутентификации в вашем приложении, такие как вход в систему, регистрация, восстановление пароля, профиль пользователя и многое другое. Для начала добавьте в приложение целевую страницу, которая будет выступать в качестве средства аутентификации для основного приложения.
Материал или приложение Купертино
FlutterFire UI требует, чтобы ваше приложение было обернуто либо в MaterialApp , либо в CupertinoApp . В зависимости от вашего выбора, пользовательский интерфейс автоматически отобразит различия между виджетами Material и Cupertino. Для этого практического занятия используйте MaterialApp , который уже добавлен в приложение в app.dart .
lib/app.dart
import 'package:flutter/material.dart';
import 'auth_gate.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: AuthGate(clientId: clientId),
);
}
}
Проверьте состояние аутентификации
Прежде чем отображать экран входа в систему, необходимо определить, аутентифицирован ли пользователь. Наиболее распространенный способ проверки этого — прослушивание authStateChanges объекта FirebaseAuth с помощью плагина Firebase Auth .
В приведенном выше примере кода MaterialApp создает виджет AuthGate в своем методе build . (Это пользовательский виджет, не предоставляемый FlutterFire UI.)
Этот виджет необходимо обновить, чтобы он включал поток authStateChanges .
API authStateChanges возвращает Stream содержащий либо текущего пользователя (если он авторизован), либо null, если он не авторизован. Чтобы подписаться на это состояние в нашем приложении, вы можете использовать виджет `StreamBuilder` из Flutter и передать ему поток.
StreamBuilder — это виджет, который автоматически создается на основе последнего снимка данных из переданного ему потока . Он автоматически перестраивается, когда Stream генерирует новый снимок.
Обновите код в auth_gate.dart .
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider; // Add this import
import 'package:firebase_ui_auth/firebase_ui_auth.dart'; // And this import
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>( // Modify from here...
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(providers: []);
}
return const HomeScreen();
},
); // To here.
}
}
StreamBuilder.streamпередаетсяFirebaseAuth.instance.authStateChanged, упомянутый выше поток, который вернет объект FirebaseUser, если пользователь прошел аутентификацию, в противном случае он вернетnull.- Далее, код использует
snapshot.hasDataдля проверки того, содержит ли значение из потока объектUser. - Если его нет, будет возвращен виджет
SignInScreen. На данный момент этот экран ничего не делает, он будет обновлен на следующем шаге. - В противном случае возвращается
HomeScreen, основная часть приложения, доступная только авторизованным пользователям.
SignInScreen — это виджет из пакета FlutterFire UI. Именно ему будет посвящен следующий шаг этого практического занятия. После запуска приложения вы должны увидеть пустой экран входа в систему.
5. Экран входа в систему
Виджет SignInScreen , предоставляемый FlutterFire UI, добавляет следующую функциональность:
- Позволяет пользователям входить в систему.
- Если пользователи забыли свой пароль, они могут нажать «Забыли пароль?» и перейти к форме для сброса пароля.
- Если пользователь еще не зарегистрирован, он может нажать кнопку «Зарегистрироваться», и его перенаправят на другую форму, позволяющую зарегистрироваться.
Опять же, для этого требуется всего пара строк кода. Вспомним код в виджете AuthGate :
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(providers: [EmailAuthProvider()]); // Modify this line
}
return const HomeScreen();
},
);
}
}
Для получения всей вышеописанной функциональности требуется только виджет SignInScreen и его аргумент providers . Теперь вы должны увидеть экран входа в систему с полями для ввода адреса электронной почты и пароля, а также кнопкой «Войти».
Несмотря на функциональность, виджету не хватает стилизации. Он предоставляет параметры для настройки внешнего вида экрана входа в систему. Например, вы можете захотеть добавить логотип вашей компании.
Настройка экрана входа в систему
Конструктор заголовков
Используя аргумент SignInScreen.headerBuilder , вы можете добавить любые виджеты над формой входа. Этот виджет отображается только на узких экранах, таких как мобильные устройства. На широких экранах можно использовать SignInScreen.sideBuilder , который будет рассмотрен позже в этом практическом занятии.
Обновите файл lib/auth_gate.dart , добавив следующий код:
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen( // Modify from here...
providers: [EmailAuthProvider()],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
); // To here.
}
return const HomeScreen();
},
);
}
}
Аргумент headerBuilder требует наличия функции типа HeaderBuilder, которая определена в пакете FlutterFire UI.
typedef HeaderBuilder = Widget Function(
BuildContext context,
BoxConstraints constraints,
double shrinkOffset,
);
Поскольку это функция обратного вызова, она предоставляет значения, которые вы можете использовать, такие как BuildContext и BoxConstraints , и требует возврата виджета. Какой бы виджет вы ни вернули, он отобразится в верхней части экрана. В этом примере новый код добавляет изображение в верхнюю часть экрана. Теперь ваше приложение должно выглядеть так.

Конструктор субтитров
На экране входа в систему отображаются три дополнительных параметра, позволяющих настроить экран: subtitleBuilder , footerBuilder и sideBuilder .
subtitleBuilder немного отличается тем, что в качестве аргументов обратного вызова используется действие типа AuthAction . AuthAction — это перечисление, которое можно использовать для определения того, находится ли пользователь на экране «вход в систему» или «регистрация».
Обновите код в lib/auth_gate.dart , чтобы использовать subtitleBuilder .
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [EmailAuthProvider()],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) { // Add from here...
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
}, // To here.
);
}
return const HomeScreen();
},
);
}
}
Конструктор нижнего колонтитула
Аргумент footerBuilder аналогичен аргументу subtitleBuilder. Он не предоставляет возможности использования BoxConstraints или shrinkOffset , поскольку предназначен для текста, а не для изображений. Конечно, вы можете добавить любой виджет по своему желанию.
Добавьте нижний колонтитул на экран входа в систему с помощью этого кода.
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [EmailAuthProvider()],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) { // Add from here...
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
}, // To here.
);
}
return const HomeScreen();
},
);
}
}
Side Builder
Аргумент SignInScreen.sidebuilder принимает функцию обратного вызова, и в данном случае аргументами этой функции являются BuildContext и double shrinkOffset . Виджет, возвращаемый sideBuilder , будет отображаться слева от формы входа и только на широких экранах. Фактически это означает, что виджет будет отображаться только в настольных и веб-приложениях.
Внутри FlutterFire UI используется точка останова для определения того, следует ли отображать содержимое заголовка (на высоких экранах, например, мобильных устройствах) или боковое содержимое (на широких экранах, настольных компьютерах или в веб-браузере). В частности, если ширина экрана превышает 800 пикселей, отображается боковое содержимое конструктора, а содержимое заголовка — нет. Если ширина экрана меньше 800 пикселей, то верно обратное.
Обновите код в lib/auth_gate.dart , чтобы добавить виджеты sideBuilder .
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [EmailAuthProvider()],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
sideBuilder: (context, shrinkOffset) { // Add from here...
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
); // To here.
},
);
}
return const HomeScreen();
},
);
}
}
Теперь ваше приложение должно выглядеть так, когда вы увеличите ширину окна (если вы используете Flutter web или macOS).

Создать пользователя
На данном этапе весь код для этого экрана готов. Однако, прежде чем вы сможете войти в систему, вам необходимо создать пользователя. Это можно сделать на экране «Регистрация» или создать пользователя в консоли Firebase.
Чтобы воспользоваться консолью:
- Перейдите в таблицу "Пользователи" в консоли Firebase . Выберите "flutterfire-ui-codelab" или другой проект, если вы использовали другое имя. Вы увидите следующую таблицу:

- Нажмите кнопку «Добавить пользователя».

- Введите адрес электронной почты и пароль для нового пользователя. Это могут быть фиктивные адрес электронной почты и пароль, как показано на изображении ниже. Это сработает, но функция «Забыли пароль?» не будет работать, если вы используете фиктивный адрес электронной почты.

- Нажмите «Добавить пользователя».

Теперь вы можете вернуться к своему Flutter-приложению и авторизовать пользователя, используя страницу входа. Ваше приложение должно выглядеть примерно так:

6. Экран профиля
FlutterFire UI также предоставляет виджет ProfileScreen , который, опять же, дает вам множество функций всего в нескольких строках кода.
Добавить виджет ProfileScreen
Перейдите в текстовый редактор к файлу home.dart . Обновите его, добавив следующий код:
lib/home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => const ProfileScreen(),
),
);
},
),
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
SizedBox(width: 250, child: Image.asset('assets/dash.png')),
Text('Welcome!', style: Theme.of(context).textTheme.displaySmall),
const SignOutButton(),
],
),
),
);
}
}
Важный новый фрагмент кода — это функция обратного вызова, передаваемая методу IconButton.isPressed . При нажатии на эту IconButton ваше приложение создает новый анонимный маршрут и переходит по нему. На этом маршруте будет отображаться виджет ProfileScreen , который возвращается из функции обратного вызова MaterialPageRoute.builder .
Перезагрузите приложение и нажмите на значок в правом верхнем углу (на панели приложения). Отобразится страница, похожая на эту:

Это стандартный пользовательский интерфейс, предоставляемый страницей FlutterFire UI. Все кнопки и текстовые поля подключены к Firebase Auth и работают «из коробки». Например, вы можете ввести имя в текстовое поле «Имя», и FlutterFire UI вызовет метод FirebaseAuth.instance.currentUser?.updateDisplayName , который сохранит это имя в Firebase.
Выход
В настоящий момент, если вы нажмете кнопку «Выйти», приложение не изменится. Вы выйдете из системы, но вас не перенаправят обратно к виджету AuthGate. Для реализации этой функции используйте параметр ProfileScreen.actions.
Сначала обновите код в файле home.dart.
lib/home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
}),
],
),
),
);
},
),
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
SizedBox(width: 250, child: Image.asset('assets/dash.png')),
Text('Welcome!', style: Theme.of(context).textTheme.displaySmall),
const SignOutButton(),
],
),
),
);
}
}
Теперь, при создании экземпляра ProfileScreen , вы также передаете ему список действий в аргумент ProfileScreen.actions . Эти действия имеют тип FlutterFireUiAction . Существует множество различных классов, являющихся подтипами FlutterFireUiAction , и в целом вы используете их, чтобы указать вашему приложению реагировать на различные изменения состояния аутентификации. SignedOutAction вызывает функцию обратного вызова, которую вы ему передаете, когда состояние аутентификации Firebase изменяется на значение currentUser, равное null.
Добавив функцию обратного вызова, которая вызывает Navigator.of(context).pop() при срабатывании SignedOutAction , приложение перейдет на предыдущую страницу. В этом примере приложения есть только один постоянный маршрут, который отображает экран входа в систему, если пользователь не авторизован, и домашнюю страницу, если пользователь авторизован. Поскольку это происходит при выходе пользователя из системы, приложение отобразит экран входа в систему.
Настройте страницу профиля
Как и экран входа в систему, страница профиля настраивается. Во-первых, на текущей странице нет возможности вернуться на главную страницу после того, как пользователь находится на странице профиля. Исправьте это, добавив в виджет ProfileScreen панель приложений (AppBar).
lib/home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(title: const Text('User Profile')),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
}),
],
),
),
);
},
),
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
SizedBox(width: 250, child: Image.asset('assets/dash.png')),
Text('Welcome!', style: Theme.of(context).textTheme.displaySmall),
const SignOutButton(),
],
),
),
);
}
}
Аргумент ProfileScreen.appBar принимает виджет AppBar из пакета Flutter Material, поэтому его можно рассматривать как любой другой AppBar который вы создали и передали в Scaffold . В этом примере сохраняется стандартная функциональность автоматического добавления кнопки «Назад», а экран теперь имеет заголовок.
Добавить детей на экран профиля
Виджет ProfileScreen также имеет необязательный аргумент с именем children. Этот аргумент принимает список виджетов, которые будут размещены вертикально внутри виджета Column , уже используемого внутри для построения ProfileScreen . Этот виджет Column в методе построения ProfileScreen разместит переданные ему дочерние элементы над кнопкой «Выйти».
Обновите код в home.dart , чтобы здесь отображался логотип компании, как на экране входа в систему.
lib/home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(title: const Text('User Profile')),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
}),
],
children: [
const Divider(),
Padding(
padding: const EdgeInsets.all(2),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
),
],
),
),
);
},
),
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
SizedBox(width: 250, child: Image.asset('assets/dash.png')),
Text('Welcome!', style: Theme.of(context).textTheme.displaySmall),
const SignOutButton(),
],
),
),
);
}
}
Перезагрузите приложение, и на экране вы увидите следующее:

7. Многоплатформенный вход через Google Auth.
FlutterFire UI также предоставляет виджеты и функциональность для аутентификации у сторонних поставщиков, таких как Google, Twitter, Facebook, Apple и GitHub.
Для интеграции с аутентификацией Google установите официальный плагин firebase_ui_oauth_google и его зависимости, которые будут обрабатывать нативный процесс аутентификации. В терминале перейдите в корневую папку вашего проекта Flutter и введите следующую команду:
flutter pub add google_sign_in firebase_ui_oauth_google
Включить Google Sign-in Provider
Далее включите провайдер Google в консоли Firebase :
- Перейдите на экран «Поставщики аутентификации» в консоли.
- Нажмите «Добавить нового поставщика».

- Выберите «Google».

- Переключите тумблер с надписью «Включить» и нажмите «Сохранить».

- Если появится всплывающее окно с информацией о загрузке конфигурационных файлов, нажмите «Готово».
- Убедитесь, что поставщик услуг авторизации Google добавлен.

Добавить кнопку входа через Google.
При включенной авторизации через Google добавьте виджет, необходимый для отображения стилизованной кнопки авторизации Google на экране входа. Перейдите к файлу auth_gate.dart и обновите код следующим образом:
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:firebase_ui_oauth_google/firebase_ui_oauth_google.dart'; // Add this import
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
GoogleProvider(clientId: clientId), // Add this line
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
sideBuilder: (context, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Единственное новое изменение в коде — это добавление параметра GoogleProvider(clientId: "YOUR_WEBCLIENT_ID") в конфигурацию виджета SignInScreen .
После добавления этой информации перезагрузите приложение, и вы увидите кнопку входа через Google.

Настройка кнопки входа в систему
Кнопка не работает без дополнительной настройки. Если вы разрабатываете с использованием Flutter Web, это единственный шаг, который вам нужно добавить для корректной работы. Для других платформ требуются дополнительные шаги, которые будут рассмотрены чуть позже.
- Перейдите на страницу «Поставщики аутентификации» в консоли Firebase .
- Нажмите на поставщика услуг Google.

- Щёлкните по панели расширения «Конфигурация Web SDK».
- Скопируйте значение из поля "Идентификатор веб-клиента".

- Вернитесь в текстовый редактор и обновите экземпляр
GoogleProviderв файлеauth_gate.dart, передав этот ID параметруclientId.
GoogleProvider(
clientId: "YOUR_WEBCLIENT_ID"
)
После ввода веб-идентификатора перезагрузите приложение. При нажатии кнопки «Войти через Google» откроется новое окно (если вы используете веб-версию), которое проведет вас через процесс входа через Google. Изначально это выглядит так:

Настройка iOS
Для корректной работы на iOS требуется дополнительная настройка.
- Перейдите на экран «Настройки проекта» в консоли Firebase . Там вы увидите карточку со списком ваших приложений Firebase, которая выглядит примерно так:

- Выберите iOS. Обратите внимание, что название вашего приложения будет отличаться от показанного на скриншоте. Там, где на скриншоте написано «complete», у вас будет написано «start», если вы использовали проект
flutter-codelabs/firebase-auth-flutterfire-ui/startдля выполнения этого задания. - Нажмите кнопку
GoogleServices-Info.plist, чтобы загрузить необходимый конфигурационный файл.
- Перетащите загруженный файл в папку
/ios/Runnerв вашем проекте Flutter. - Откройте Xcode, выполнив следующую команду в терминале из корневой папки вашего проекта:
open ios/Runner.xcworkspace - Щелкните правой кнопкой мыши на папке Runner и выберите «Добавить файлы в Runner».

- Выберите файл
GoogleService-Info.plistв файловом менеджере. - Вернитесь в свой текстовый редактор (кроме Xcode) и добавьте указанные ниже атрибуты
CFBundleURLTypesв файлios/Runner/Info.plist. Убедитесь, что вы заменилиREVERSE_CLIENT_IDна значение, скопированное изGoogleService-Info.plist.<!-- Put me in the [my_project]/ios/Runner/Info.plist file --> <!-- Google Sign-in Section --> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <!-- TODO Replace this value: --> <!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID --> <string>REVERSE_CLIENT_ID</string> </array> </dict> </array> <!-- End of the Google Sign-in Section --> - Повторите команду
flutterfire configure, чтобы обновить файлfirebase_options.dart. Если CLI спросит, хотите ли вы повторно использовать существующий файлfirebase.json, выберите «да». - Вам необходимо заменить
GoogleProvider.clientId, который вы добавили при веб-настройке, на Client Id, связанный с вашим iOS-клиентом Firebase. Во-первых, вы можете найти этот ID в файлеfirebase_options.dart, как часть константыiOS. Скопируйте значение, переданное вiOSClientId.static const FirebaseOptions ios = FirebaseOptions( apiKey: 'YOUR API KEY', appId: 'YOUR APP ID', messagingSenderId: '', projectId: 'PROJECT_ID', storageBucket: 'PROJECT_ID.firebasestorage.app', iosClientId: 'IOS CLIENT ID', // Find your iOS client Id here. iosBundleId: 'com.example.BUNDLE', ); - Вставьте это значение в переменную
clientIdв файлеlib/main.dart.
lib/main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'app.dart';
import 'firebase_options.dart';
const clientId = 'YOUR_CLIENT_ID'; // Replace this value with your iosClientId.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(const MyApp(clientId: clientId));
}
Если ваше Flutter-приложение уже запущено на iOS, вам необходимо полностью закрыть его, а затем запустить заново. В противном случае запустите приложение на iOS.
Настройка Android
Для использования Google Sign-in на Android необходимо сначала зарегистрировать SHA-1-отпечаток вашего приложения в проекте Firebase.
- Перейдите в каталог
androidвашего проекта и выполните следующую команду, чтобы сгенерировать отчет о подписании для вашего приложения:
./gradlew signingReport
- После завершения выполнения команды вы увидите список вариантов и информацию об их подписи. Найдите ключ SHA-1 в разделе
debugварианта и скопируйте его.

- Перейдите на экран «Настройки проекта» в консоли Firebase и выберите свое приложение для Android. Нажмите кнопку
Add fingerprintи зарегистрируйте скопированный вами ключ SHA-1.

8. Поздравляем!
Вы завершили выполнение задания по созданию пользовательского интерфейса Firebase Auth для Flutter. Готовый код для этого задания можно найти в каталоге firebase-auth-flutterfire-ui/complete на GitHub .
Что мы рассмотрели
- Настройка Flutter-приложения для использования Firebase
- Настройка проекта Firebase в консоли Firebase
- FlutterFire CLI
- Firebase CLI
- Использование аутентификации Firebase
- Использование FlutterFire UI для обработки аутентификации Firebase в вашем Flutter-приложении
Следующие шаги
- Узнайте больше об использовании Firestore и аутентификации во Flutter: познакомьтесь с Firebase для Flutter на Codelab.
- Изучите другие инструменты Firebase для создания вашего Flutter-приложения:
Узнать больше
- Сайт Firebase: firebase.google.com
- Сайт Flutter: flutter.dev
- FlutterFire Firebase Flutter widgets: firebase.flutter.dev
- YouTube-канал Firebase
- YouTube-канал Flutter
Спарки здесь, чтобы отпраздновать это событие вместе с вами!
