Dodawanie do aplikacji Flutter procesu uwierzytelniania użytkownika za pomocą FirebaseUI
Informacje o tym ćwiczeniu (w Codelabs)
1. Zanim zaczniesz
Z tego Codelab dowiesz się, jak dodać uwierzytelnianie Firebase do aplikacji Flutter za pomocą pakietu interfejsu użytkownika FlutterFire. Dzięki temu pakietowi możesz dodać do aplikacji Flutter uwierzytelnianie za pomocą adresu e-mail i hasła oraz logowanie Google. Dowiesz się też, jak skonfigurować projekt Firebase i użyć wiersza poleceń FlutterFire do zainicjowania Firebase w aplikacji Flutter.
Wymagania wstępne
To ćwiczenie z programowania zakłada, że masz już pewne doświadczenie w używaniu Fluttera. Jeśli nie, warto najpierw zapoznać się z podstawami. Te linki mogą być przydatne:
- Prezentacja frameworku widżetów Fluttera
- Wypróbuj ćwiczenie Tworzenie pierwszej aplikacji Flutter, część 1.
Powinieneś/powinnaś też mieć pewne doświadczenie w korzystaniu z Firebase, ale nie ma problemu, jeśli nie dodawałeś/dodawałaś Firebase do projektu Flutter. Jeśli nie znasz konsoli Firebase lub dopiero zaczynasz korzystać z tej platformy, zapoznaj się najpierw z tymi artykułami:
Co utworzysz
Ten projekt poprowadzi Cię przez proces tworzenia przepływu uwierzytelniania w aplikacji Flutter, korzystając z Firebase do uwierzytelniania. Aplikacja będzie zawierać ekran logowania, ekran rejestracji, ekran odzyskiwania hasła i ekran profilu użytkownika.
Czego się nauczysz
W tym ćwiczeniu z programowania omawiamy:
- Dodawanie Firebase do aplikacji Flutter
- Konfiguracja konsoli Firebase
- Dodawanie Firebase do aplikacji za pomocą wiersza poleceń Firebase
- Generowanie konfiguracji Firebase w języku Dart za pomocą wiersza poleceń FlutterFire
- Dodawanie Uwierzytelniania Firebase do aplikacji Flutter
- Konfigurowanie Uwierzytelniania Firebase w konsoli
- Dodawanie logowania za pomocą adresu e-mail i hasła w pakiecie
firebase_ui_auth
- Dodawanie rejestracji użytkownika w pakiecie
firebase_ui_auth
- Dodawanie strony „Nie pamiętasz hasła?”
- Dodawanie logowania przez Google za pomocą
firebase_ui_auth
- Skonfiguruj aplikację do współpracy z wieloma dostawcami logowania.
- Dodawanie ekranu profilu użytkownika do aplikacji za pomocą pakietu
firebase_ui_auth
W tym laboratorium programistycznym skupiamy się na dodaniu niezawodnego systemu uwierzytelniania za pomocą pakietu firebase_ui_auth
. Jak zobaczysz, całą aplikację ze wszystkimi wymienionymi funkcjami można zaimplementować za pomocą około 100 wierszy kodu.
Czego potrzebujesz
- Znajomość Fluttera i zainstalowanego pakietu SDK.
- edytor tekstu (Flutter obsługuje JetBrains IDE, Android Studio i VS Code);
- przeglądarka Google Chrome lub inny preferowany cel programowania dla Fluttera. (niektóre polecenia terminala w tym CodeLab będą zakładać, że aplikacja jest uruchamiana w Chrome)
2. Tworzenie i konfigurowanie projektu Firebase
Pierwszym zadaniem, które musisz wykonać, jest utworzenie projektu Firebase w konsoli internetowej Firebase.
Tworzenie projektu Firebase
- Zaloguj się w Firebase.
- W konsoli Firebase kliknij Dodaj projekt (lub Utwórz projekt) i wpisz nazwę projektu Firebase (np. „FlutterFire-UI-Codelab”).
- Przejrzyj opcje tworzenia projektu. Zaakceptuj warunki korzystania z Firebase, jeśli pojawi się taka prośba. Pomiń konfigurowanie Google Analytics, ponieważ nie będziesz używać tej usługi w przypadku tej aplikacji.
Więcej informacji o projektach Firebase znajdziesz w artykule Informacje o projektach Firebase.
Włączanie logowania za pomocą adresu e-mail w usłudze Uwierzytelnianie Firebase
Aplikacja, którą tworzysz, korzysta z usługi Uwierzytelnianie Firebase, aby umożliwić użytkownikom logowanie się w niej. Umożliwia też nowym użytkownikom rejestrację w aplikacji Flutter.
Uwierzytelnianie Firebase musi zostać włączone w konsoli Firebase, a po włączeniu wymaga specjalnej konfiguracji.
Aby umożliwić użytkownikom logowanie się w aplikacji internetowej, najpierw użyj metody logowania E-mail/hasło. Później dodasz metodę Logowania przez Google.
- W konsoli Firebase rozwiń w panelu po lewej stronie menu Kompilacja.
- Kliknij Uwierzytelnianie, a następnie kliknij przycisk Rozpocznij i kartę Metoda logowania (lub kliknij tutaj, aby przejść bezpośrednio do karty Metoda logowania).
- Na liście Dostawcy logowania kliknij E-mail/hasło, ustaw przełącznik Włącz w pozycji włączonej, a następnie kliknij Zapisz.
3. Konfigurowanie aplikacji Flutter
Zanim zaczniesz, musisz pobrać kod startowy i zainstalować wiersz poleceń Firebase.
Pobieranie kodu startowego
Sklonuj repozytorium GitHub z poziomu wiersza poleceń:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
Jeśli masz zainstalowane narzędzie wiersza poleceń GitHub :
gh repo clone flutter/codelabs flutter-codelabs
Przykładowy kod należy sklonować do katalogu flutter-codelabs
na komputerze, który zawiera kod kolekcji Codelabs. Kod tego CodeLab znajduje się w podkatalogu flutter-codelabs/firebase-auth-flutterfire-ui
.
Katalog flutter-codelabs/firebase-auth-flutterfire-ui
zawiera 2 projekty Fluttera. Jedna to complete
, a druga start
. Katalog start
zawiera niekompletny projekt, na którym spędzisz najwięcej czasu.
cd flutter-codelabs/firebase-auth-flutterfire-ui/start
Jeśli chcesz przejść do następnego zadania lub sprawdzić, jak powinno wyglądać zadanie po jego ukończeniu, zajrzyj do katalogu o nazwie complete.
Jeśli chcesz wykonać ćwiczenie Codelab i sam dodać kod, zacznij od aplikacji Flutter (flutter-codelabs/firebase-auth-flutterfire-ui/start
) i dodawaj kod do tego projektu w trakcie wykonywania ćwiczenia. Otwórz ten katalog lub zaimportuj go do preferowanego środowiska IDE.
Zainstaluj wiersz poleceń Firebase
Wiersz poleceń Firebase zawiera narzędzia do zarządzania projektami Firebase. Interfejs wiersza poleceń jest wymagany do interfejsu wiersza poleceń FlutterFire, który zainstalujesz za chwilę.
Istnieją różne sposoby instalacji interfejsu wiersza poleceń. Jeśli używasz systemu MacOS lub Linux, najprostszym sposobem jest uruchomienie tego polecenia w terminalu:
curl -sL https://firebase.tools | bash
Po zainstalowaniu wiersza poleceń musisz się uwierzytelnić w Firebase.
- Zaloguj się w Firebase za pomocą konta Google, uruchamiając to polecenie:
firebase login
- To polecenie łączy Twój komputer lokalny z Firebase i daje Ci dostęp do projektów Firebase.
- Sprawdź, czy wiersz poleceń jest prawidłowo zainstalowany i czy ma dostęp do Twojego konta, wyświetlając listę projektów Firebase. Uruchom to polecenie:
firebase projects:list
- Wyświetlona lista powinna być taka sama jak projekty Firebase wymienione w konsoli Firebase. Powinieneś zobaczyć co najmniej
flutterfire-ui-codelab.
Instalowanie interfejsu wiersza poleceń FlutterFire
FlutterFire CLI to narzędzie, które ułatwia proces instalacji Firebase na wszystkich obsługiwanych platformach w aplikacji Flutter. Jest ono oparte na wierszu poleceń Firebase.
Najpierw zainstaluj interfejs wiersza poleceń:
dart pub global activate flutterfire_cli
Sprawdź, czy interfejs wiersza poleceń został zainstalowany. Uruchom to polecenie i upewnij się, że interfejs wiersza poleceń wyświetla menu pomocy.
flutterfire --help
Dodawanie projektu Firebase do aplikacji Flutter
Konfigurowanie FlutterFire
Za pomocą FlutterFire możesz wygenerować kod Darta potrzebny do korzystania z Firebase w aplikacji Flutter.
flutterfire configure
Po wykonaniu tego polecenia pojawi się prośba o wybranie projektu Firebase, którego chcesz użyć, i platform, które chcesz skonfigurować.
Na poniższych zrzutach ekranu widać prompty, na które musisz odpowiedzieć.
- Wybierz projekt, którego chcesz użyć. W tym przypadku użyj
flutterfire-ui-codelab
- Wybierz platformy, których chcesz używać. W tym laboratorium programistycznym znajdziesz instrukcje konfigurowania uwierzytelniania Firebase dla Fluttera na potrzeby wersji na web, iOS i Androida, ale możesz też skonfigurować projekt Firebase tak, aby korzystał ze wszystkich opcji.
- Ten zrzut ekranu przedstawia dane wyjściowe po zakończeniu procesu. Jeśli znasz Firebase, zauważysz, że nie musisz tworzyć aplikacji platformowych (np. aplikacji na Androida) w konsoli. Za Ciebie zrobi to interfejs wiersza poleceń FlutterFire.
Gdy to zrobisz, otwórz aplikację Flutter w edytorze tekstu. Interfejs wiersza poleceń FlutterFire wygenerował nowy plik o nazwie firebase_options.dart
. Plik ten zawiera klasę o nazwie FirebaseOptions, która zawiera zmienne statyczne zawierające konfigurację Firebase potrzebną na każdej platformie. Jeśli podczas wykonywania testu flutterfire configure
wybrano wszystkie platformy, zobaczysz wartości statyczne o nazwach web
, android
, ios
i macos
.
firebase_options.dart
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
// ignore: missing_enum_constant_in_switch
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
}
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 używa słowa „aplikacja” w przypadku konkretnej kompilacji dla konkretnej platformy w projekcie Firebase. Na przykład projekt Firebase o nazwie FlutterFire-ui-codelab zawiera kilka aplikacji: jedną na Androida, jedną na iOS, jedną na MacOS i jedną na internet.
Metoda DefaultFirebaseOptions.currentPlatform
używa enumeracji TargetPlatform
udostępnionej przez Fluttera, aby wykryć platformę, na której działa aplikacja, a następnie zwraca wartości konfiguracji Firebase potrzebne do prawidłowego zastosowania Firebase.
Dodawanie pakietów Firebase do aplikacji Flutter
Ostatnim krokiem konfiguracji jest dodanie odpowiednich pakietów Firebase do projektu Flutter. Plik firebase_options.dart
powinien zawierać błędy, ponieważ korzysta z pakietów Firebase, które nie zostały jeszcze dodane. W terminalu upewnij się, że znajdujesz się w katalogu głównym projektu Flutter (flutter-codelabs/firebase-emulator-suite/start
). Następnie uruchom te 3 polecenia:
flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add firebase_ui_auth
Na tym etapie są to jedyne potrzebne pakiety.
Inicjowanie Firebase
Aby używać dodanych pakietów i funkcji DefaultFirebaseOptions.currentPlatform,
, zaktualizuj kod w funkcji main
w pliku main.dart
.
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
Ten kod wykonuje 2 działania.
WidgetsFlutterBinding.ensureInitialized()
informuje Fluttera, aby nie uruchamiał kodu widżetu aplikacji, dopóki nie uruchomi się cały framework Fluttera. Firebase korzysta z kanałów natywnych platform, które wymagają uruchomionego frameworku.Firebase.initializeApp
łączy aplikację Flutter z projektem Firebase. PlikDefaultFirebaseOptions.currentPlatform
jest importowany z wygenerowanego plikufirebase_options.dart
. Ta wartość statyczna wykrywa, na jakiej platformie działasz, i przekazuje odpowiednie klucze Firebase.
4. Dodawanie początkowej strony uwierzytelniania w interfejsie Firebase
Interfejs Firebase dla usługi Uwierzytelnianie zawiera widżety, które reprezentują całe ekrany w aplikacji. Te ekrany obsługują różne przepływy uwierzytelniania w aplikacji, takie jak logowanie, rejestracja, hasło zostało zapomniane czy profil użytkownika. Aby zacząć, dodaj do aplikacji stronę docelową, która będzie pełnić funkcję zabezpieczenia uwierzytelniania dla aplikacji głównej.
Materiał lub aplikacja Cupertino
Interfejs FlutterFire wymaga, aby aplikacja była owinięta w klasę MaterialApp lub CupertinoApp. W zależności od wybranej opcji interfejs będzie automatycznie odzwierciedlał różnice między widżetami Material i Cupertino. W tym ćwiczeniu użyj MaterialApp
, który został już dodany do aplikacji w wersji app.dart
.
app.dart
import 'package:flutter/material.dart';
import 'auth_gate.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const AuthGate(),
);
}
}
Sprawdzanie stanu uwierzytelniania
Zanim wyświetlisz ekran logowania, musisz sprawdzić, czy użytkownik jest obecnie uwierzytelniony. Najczęstszym sposobem sprawdzania tego jest słuchanie zdarzeń authStateChanges w FirebaseAuth za pomocą wtyczki Firebase Auth.
W przykładowym kodzie powyżej klasa MaterialApp
tworzy widżet AuthGate
w swojej metodzie build(). (to widżet niestandardowy, który nie jest dostarczany przez interfejs użytkownika FlutterFire).
Widżet musi zostać zaktualizowany, aby uwzględniał strumień authStateChanges
.
Interfejs API authStateChanges
zwraca Stream
z bieżącym użytkownikiem (jeśli jest zalogowany) lub null, jeśli tak nie jest. Aby subskrybować ten stan w naszej aplikacji, możesz użyć widżetu StreamBuilder w Flutterze i przekazać mu strumień.
StreamBuilder
to widżet, który sam się tworzy na podstawie najnowszego zrzutu danych ze strumienia, który mu przekazujesz. Jest ona automatycznie odtwarzana, gdy strumień wyemituje nowy zrzut.
Zaktualizuj kod w auth_gate.dart
.
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});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [],
);
}
return const HomeScreen();
},
);
}
}
StreamBuilder.stream
jest przekazywanyFirebaseAuth.instance.authStateChanged
, wspomniany wcześniej strumień, który zwróci obiekt FirebaseUser
, jeśli użytkownik został uwierzytelniony. (w przeciwnym razie zwraca wartośćnull
).- Następnie kod używa funkcji
snapshot.hasData
, aby sprawdzić, czy wartość ze strumienia zawiera obiektUser
. - Jeśli nie ma żadnych, zwróci widżet
SignInScreen
. Obecnie ten ekran nie robi nic. Zostanie to zaktualizowane w kolejnym kroku. - W przeciwnym razie zwraca
HomeScreen
, czyli główną część aplikacji, do której dostęp mają tylko uwierzytelnieni użytkownicy.
SignInScreen
to widżet pochodzący z pakietu interfejsu użytkownika FlutterFire. Na tym skupimy się w następnym kroku tego samouczka. Gdy uruchomisz aplikację, powinien pojawić się pusty ekran logowania.
5. Ekran logowania
Widżet SignInScreen
udostępniany przez interfejs FlutterFire UI dodaje te funkcje:
- Zezwalanie użytkownikom na logowanie
- Jeśli użytkownik zapomni hasło, może kliknąć „Nie pamiętam hasła?”, aby przejść do formularza resetowania hasła.
- Jeśli użytkownik nie jest jeszcze zarejestrowany, może kliknąć „Zarejestruj się” i zostanie przekierowany do innego formularza, który pozwoli mu się zarejestrować.
To wymaga tylko kilku linii kodu. Przypomnij kod w widżecie AuthGate:
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});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(), // new
],
);
}
return const HomeScreen();
},
);
}
}
Widget SignInScreen
i jego argument providers
to jedyny kod wymagany do uzyskania wszystkich wymienionych funkcji. Powinien wyświetlić się ekran logowania z polami tekstowymi „E-mail” i „Hasło” oraz przyciskiem „Zaloguj się”.
Chociaż jest funkcjonalna, brakuje jej stylu. Widget udostępnia parametry, które umożliwiają dostosowanie wyglądu ekranu logowania. Możesz na przykład dodać logo swojej firmy.
Dostosowywanie ekranu logowania
headerBuilder
Za pomocą argumentu SignInScreen.headerBuilder
możesz dodawać dowolne widżety nad formularzem logowania. Ten widżet jest wyświetlany tylko na wąskich ekranach, np. na urządzeniach mobilnych. Na szerokich ekranach możesz użyć SignInScreen.sideBuilder
, o którym mowa w dalszej części tego Codelab.
Zaktualizuj plik auth_gate.dart
za pomocą tego kodu:
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});
@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'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Argument headerBuilder wymaga funkcji typu HeaderBuilder, która jest zdefiniowana w pakiecie FlutterFire UI.
typedef HeaderBuilder = Widget Function(
BuildContext context,
BoxConstraints constraints,
double shrinkOffset,
);
Jest to funkcja zwracająca wartość, która udostępnia wartości, których możesz użyć, np. BuildContext
i BoxConstraints
, oraz wymaga zwrócenia widżetu. Wyświetli się wybrany widżet u góry ekranu. W tym przykładzie nowy kod dodaje obraz u góry ekranu. Twoja aplikacja powinna teraz wyglądać tak.
Subtitle Builder
Ekran logowania zawiera 3 dodatkowe parametry, które umożliwiają jego dostosowywanie: subtitleBuilder
, footerBuilder
i sideBuilder
.
Funkcja subtitleBuilder
różni się nieznacznie tym, że argumenty wywołania zwrotnego zawierają działanie o typie AuthAction
. AuthAction
to typ enumeracji, który umożliwia wykrycie, czy użytkownik znajduje się na ekranie logowania czy rejestracji.
Zaktualizuj kod w pliku auth_gate.dart, aby używać funkcji subtitleBuilder.
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});
@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('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!'),
);
},
);
}
return const HomeScreen();
},
);
}
}
Załaduj ponownie aplikację. Powinna wyglądać tak
Kreator stopki
Argument footerBuilder jest taki sam jak argument subtitleBuilder. Nie zawiera ona tagów BoxConstraints
ani shrinkOffset
, ponieważ jest przeznaczona do tekstu, a nie obrazów. (chociaż możesz dodać dowolny widżet).
Dodaj stopkę do ekranu logowania za pomocą tego kodu.
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});
@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('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),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Side Builder
Argument SignInScreen.sidebuilder akceptuje wywołanie zwrotne, a tym razem argumentami tego wywołania są BuildContext
i double shrinkOffset
. Widżet zwracany przez sideBuilder będzie wyświetlany po lewej stronie formularza logowania i tylko na ekranach panoramicznych. Oznacza to, że widżet będzie wyświetlany tylko w aplikacjach internetowych i na komputerach.
Wewnętrznie interfejs FlutterFire używa punktu przełamania, aby określić, czy wyświetlić zawartość nagłówka (na wysokich ekranach, np. na urządzeniach mobilnych) czy zawartość boczną (na szerokich ekranach, na komputerach lub w przeglądarce). Jeśli ekran ma więcej niż 800 pikseli szerokości, wyświetlana jest zawartość kreatora bocznego, a nie nagłówka. Jeśli ekran ma mniej niż 800 pikseli, jest odwrotnie.
Zaktualizuj kod w pliku auth_gate.dart, aby dodać widżety sideBuilder.
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});
@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('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('flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Po rozwinięciu okna aplikacja powinna wyglądać tak (jeśli używasz Fluttera w wersji internetowej lub na macOS).
Tworzenie konta użytkownika
Na tym etapie cały kod tego ekranu jest gotowy. Zanim się zalogujesz, musisz utworzyć użytkownika. Możesz to zrobić na ekranie „Zarejestruj się” lub utworzyć użytkownika w konsoli Firebase.
Aby korzystać z konsoli:
- W konsoli Firebase otwórz tabelę „Użytkownicy”.
- Kliknij tutaj
- Wybierz „flutterfire-ui-codelab” (lub inny projekt, jeśli użyto innej nazwy). Zobaczysz tę tabelę:
- Kliknij przycisk „Dodaj użytkownika”.
- Wpisz adres e-mail i hasło nowego użytkownika. Może to być fałszywy adres e-mail i fałszywe hasło, jak widać na obrazku poniżej. To zadziała, ale funkcja „Nie pamiętam hasła” nie będzie działać, jeśli użyjesz fałszywego adresu e-mail.
- Kliknij „Dodaj użytkownika”.
Możesz teraz wrócić do aplikacji Flutter i zalogować użytkownika na stronie logowania. Twoja aplikacja powinna wyglądać tak:
6. Ekran profilu
Interfejs FlutterFire udostępnia też widżet ProfileScreen
, który zapewnia wiele funkcji w kilku linijkach kodu.
Dodawanie widżetu ProfileScreen
W edytorze tekstu przejdź do pliku home.dart
. Zaktualizuj go za pomocą tego kodu:
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: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Nowy kod to funkcja wywołania zwrotnego przekazana do metody IconButton.isPressed
. Gdy naciśniesz IconButton
, aplikacja utworzy nową anonimową trasę i przejdzie na nią. Ta ścieżka wyświetli widżet ProfileScreen
, który jest zwracany z trybu wywołania zwrotnego MaterialPageRoute.builder
.
Ponownie uruchom aplikację i kliknij ikonę w prawym górnym rogu (na pasku aplikacji). Pojawi się strona:
Jest to standardowy interfejs użytkownika udostępniany przez stronę interfejsu FlutterFire. Wszystkie przyciski i pola tekstowe są połączone z Uwierzytelnianiem Firebase i działają od razu po zainstalowaniu. Możesz na przykład wpisać nazwę w polu tekstowym „Nazwa”, a interfejs FlutterFire wywoła metodę FirebaseAuth.instance.currentUser?.updateDisplayName
, która zapisze tę nazwę w Firebase.
Wylogowywanie się
Jeśli teraz naciśniesz przycisk „Wyloguj”, aplikacja nie ulegnie zmianie. Spowoduje to wylogowanie, ale nie wrócisz do widżetu AuthGate. Aby to zaimplementować, użyj parametru ProfileScreen.actions.
Najpierw zaktualizuj kod w pliku home.dart.
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: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Teraz, gdy tworzysz instancję ProfileScreen
, przekazujesz jej również listę działań do argumentu ProfileScreen.actions
. Te działania są typu FlutterFireUiAction
. Istnieje wiele różnych klas, które są podtypami klasy FlutterFireUiAction
. Zazwyczaj służą one do określania sposobu reakcji aplikacji na różne zmiany stanu uwierzytelniania. Funkcja SignedOutAction wywołuje funkcję wywołania zwrotnego, którą jej przekazujesz, gdy stan uwierzytelniania Firebase zmienia się na null dla bieżącego użytkownika.
Dodanie wywołania zwrotnego, które wywołuje funkcję Navigator.of(context).pop()
, gdy zostanie wywołana akcja SignedOutAction, spowoduje przejście aplikacji do poprzedniej strony. W tej przykładowej aplikacji jest tylko jedna stała ścieżka, która wyświetla stronę logowania, jeśli użytkownik nie jest zalogowany, i stronę główną, jeśli jest zalogowany. Ponieważ dzieje się to, gdy użytkownik się wyloguje, aplikacja wyświetli stronę logowania.
Dostosowywanie strony profilu
Podobnie jak strona logowania, strona profilu umożliwia dostosowywanie. Po pierwsze, na naszej obecnej stronie nie ma możliwości powrotu na stronę główną, gdy użytkownik znajdzie się na stronie profilu. Aby rozwiązać ten problem, dodaj do widżetu ProfileScreen pasek aplikacji.
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: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Argument ProfileScreen.appBar
przyjmuje widżet AppBar
z pakietu Flutter Material, więc można go traktować jak dowolny inny widżet AppBar
, który został utworzony i przekazany do Scaffold
. W tym przykładzie zachowano domyślną funkcję automatycznego dodawania przycisku „Wstecz”, a ekran ma teraz tytuł.
Dodawanie dzieci na ekranie profilu
Widżet ProfileScreen ma też opcjonalny argument o nazwie children. Ten argument akceptuje listę widżetów, które zostaną umieszczone pionowo w widżecie kolumny, który jest już używany wewnętrznie do tworzenia ekranu ProfileScreen. Ten widżet kolumny w metodzie tworzenia ProfileScreen umieści przekazane przez Ciebie elementy nad przyciskiem „Wyloguj”.
Zaktualizuj kod w pliku home.dart, aby wyświetlić logo firmy, podobnie jak na ekranie logowania.
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('flutterfire_300x.png'),
),
),
],
),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Załaduj ponownie aplikację, a na ekranie zobaczysz to:
7. Logowanie przez Google na wielu platformach
FlutterFire UI zawiera też widżety i funkcje do uwierzytelniania się u dostawców zewnętrznych, takich jak Google, Twitter, Facebook, Apple i Github.
Aby zintegrować się z uwierzytelnianiem Google, zainstaluj oficjalny firebase_ui_oauth_google i jego zależności, które będą obsługiwać proces uwierzytelniania natywnych. W terminalu przejdź do katalogu głównego projektu Fluttera i wpisz to polecenie:
flutter pub add google_sign_in flutter pub add firebase_ui_oauth_google
Włącz dostawcę logowania przez Google
Następnie włącz dostawcę Google w konsoli Firebase:
- W konsoli otwórz ekran Dostawcy logowania z uwierzytelnianiem.
- Kliknij „Dodaj nowego dostawcę”.
- Wybierz „Google”.
- Przesuń przełącznik „Włącz” i kliknij „Zapisz”.
- Jeśli pojawi się okno z informacjami o pobieraniu plików konfiguracji, kliknij „Gotowe”.
- Sprawdź, czy dostawca logowania Google został dodany.
Dodawanie przycisku logowania przez Google
Po włączeniu logowania na konto Google dodaj na stronie logowania widżet, który umożliwia wyświetlanie stylizowanego przycisku logowania na konto Google. Otwórz plik auth_gate.dart i zaktualizuj kod, jak pokazano poniżej:
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'; // new
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
GoogleProvider(clientId: "YOUR_WEBCLIENT_ID"), // new
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('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('flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Jedynym nowym kodem jest GoogleProvider(clientId: "YOUR_WEBCLIENT_ID")
dodany do konfiguracji widżetu SignInScreen.
Po dodaniu tego elementu ponownie załaduj aplikację. Zobaczysz przycisk logowania w Google.
Konfigurowanie przycisku logowania
Przycisk nie działa bez dodatkowej konfiguracji. Jeśli tworzysz aplikację za pomocą Flutter Web, to jest jedyny krok, który musisz wykonać. Inne platformy wymagają wykonania dodatkowych czynności, które omówimy za chwilę.
- W konsoli Firebase otwórz stronę Dostawcy uwierzytelniania.
- Kliknij dostawcę Google.
- Kliknij panel „Konfiguracja SDK dla klienta internetowego”.
- Skopiuj wartość z pola „Identyfikator klienta internetowego”
- Wróć do edytora tekstu i zaktualizuj wystąpienie
GoogleProvider
w plikuauth_gate.dart
, przekazując ten identyfikator do parametru o nazwieclientId
.
GoogleProvider(
clientId: "YOUR_WEBCLIENT_ID"
)
Po wpisaniu identyfikatora klienta internetowego ponownie załaduj aplikację. Gdy naciśniesz przycisk „Zaloguj się przez Google”, pojawi się nowe okno (jeśli korzystasz z wersji internetowej), które przeprowadzi Cię przez proces logowania w Google. Początkowo wygląda to tak:
Konfigurowanie iOS
Aby funkcja działała na iOS, musisz wykonać dodatkowy proces konfiguracji.
- W konsoli Firebase otwórz ekran Ustawienia projektu. Pojawi się karta z listą aplikacji Firebase, która będzie wyglądać tak:
- Kliknij iOS. Pamiętaj, że nazwa Twojej aplikacji będzie inna niż moja. Jeśli podczas wykonywania tego ćwiczenia korzystasz z projektu
flutter-codelabs/firebase-auth-flutterfire-ui/start
, w miejscu „complete” (ukończono) u Ciebie będzie widoczne „start” (rozpoczęto). - Kliknij przycisk „GoogleServices-Info.plist”, aby pobrać potrzebny plik konfiguracji.
- Przeciągnij i upuść pobrany plik do katalogu o nazwie .
/ios/Runner
w Twoim projekcie Flutter. - Otwórz Xcode, uruchamiając to polecenie w terminalu w katalogu głównym projektu:
open ios/Runner.xcworkspace
- Kliknij prawym przyciskiem folder Runner i wybierz Dodaj pliki do „Runner”.
- W menedżerze plików wybierz plik GoogleService-Info.plist.
- W edytorze tekstu (nie Xcode) dodaj atrybuty CFBundleURLTypes podane poniżej do pliku [my_project]/ios/Runner/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>com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn</string>
</array>
</dict>
</array>
<!-- End of the Google Sign-in Section -->
- Musisz zastąpić wartość
GoogleProvider.clientId
dodaną w konfiguracji internetowej identyfikatorem klienta powiązanym z identyfikatorem klienta Firebase na iOS. Najpierw możesz znaleźć ten identyfikator w plikufirebase_options.dart
jako część stałejiOS
. Skopiuj wartość przekazaną do parametruiOSClientId
.
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',
);
- Wklej tę wartość w argumencie
GoogleProvider.clientId
w widżecieAuthGate
.
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';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
GoogleProvider(clientId: "YOUR IOS CLIENT ID"), // replace String
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('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('flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Jeśli aplikacja Flutter jest już uruchomiona na iOS, musisz ją całkowicie zamknąć i ponownie uruchomić. W przeciwnym razie uruchom aplikację na iOS.
8. Gratulacje!
Udało Ci się ukończyć ćwiczenie dotyczące interfejsu Firebase Auth dla Fluttera . Gotowy kod tego ćwiczenia z programowania znajdziesz w katalogu „complete” (pełny) na GitHubie: Flutter Codelabs
Omówione zagadnienia
- Konfigurowanie aplikacji Flutter do używania Firebase
- Konfigurowanie projektu Firebase w konsoli Firebase
- FlutterFire CLI
- wiersz poleceń Firebase
- Korzystanie z Uwierzytelniania Firebase
- Używanie interfejsu FlutterFire do łatwego obsługiwania uwierzytelniania Firebase w aplikacji Flutter
Następne kroki
- Dowiedz się więcej o używaniu Firestore i uwierzytelniania w Flutterze: Poznaj Firebase w ramach Codelab dla Fluttera.
- Poznaj inne narzędzia Firebase do tworzenia aplikacji Flutter:
- Cloud Storage
- Cloud Functions
- Baza danych czasu rzeczywistego
Więcej informacji
- Strona Firebase: firebase.google.com
- Witryna Flutter: flutter.dev
- Widgety FlutterFire Firebase Flutter: firebase.flutter.dev
- Kanał Firebase w YouTube
- Kanał Flutter w YouTube
Sparky jest tutaj, aby świętować z Tobą!