Flutter: Jak zalogować się do użytkownika za pomocą Firebase

Wydanie

25/12/18 - Zaktualizowano najnowszy fragment kodu po refaktoryzacji i wyczyszczeniu.

24/01/19 - Duplikat linku do github na początku artykułu.

23/07/19 - Dodano metodę przycinania adresu e-mail i wartości hasła

Kod źródłowy

Jeśli chcesz pominąć całą mumbo jumbo, możesz pobrać kod źródłowy tutaj

https://github.com/tattwei46/flutter_login_demo

Aktualizacja

Oto kontynuacja tego postu: Jak zrobić CRUD z Firebase RTDB. Sprawdź to!

Co to jest Flutter?

Flutter to mobilny zestaw SDK typu open source opracowany przez Google w celu tworzenia wysokiej jakości aplikacji na Androida i iOS. Pozwala to programistom nie tylko budować aplikacje o pięknym designie, płynnej animacji i dużej wydajności, ale także szybko integrować nowe funkcje. Flutter oferuje szybki rozwój dzięki stanowemu ładowaniu na gorąco i gorącemu restartowi. Mając tylko jedną bazę kodu do zarządzania, możesz zaoszczędzić dużo kosztów w porównaniu do zarządzania zarówno projektami na Androida, jak i iOS, ponieważ Flutter kompiluje go do natywnego kodu ARM. Flutter używa języka programowania Dart, który jest również opracowany przez Google.

Dlaczego Dart?

  • Krótki, mocno napisany, zorientowany obiektowo język.
  • Obsługuje kompilację just-in-time i wyprzedzającą czas.
  • JIT pozwala trzepotaniu na rekompilację kodu bezpośrednio na urządzeniu, gdy aplikacja jest nadal uruchomiona.
  • Umożliwiają szybki rozwój i umożliwiają stabilne przeładowywanie w ciągu sekundy.
  • AOT pozwala na kompilację kodu bezpośrednio w natywny kod ARM, co prowadzi do szybkiego uruchomienia i przewidywalnej wydajności.

Co to jest Firebase

Firebase to mobilna i internetowa platforma programistyczna zapewniająca programistom szeroką gamę produktów. Dzisiaj zastanowimy się, jak zbudować naszą pierwszą aplikację do trzepotania z uwierzytelnianiem Firebase i bazą danych w czasie rzeczywistym. Ta aplikacja pozwala użytkownikowi zarejestrować się lub zalogować i wykonać todo CRUD za pomocą Firebase. W tym poście skupimy się wyłącznie na części rejestracji i logowania użytkownika.

Jak skonfigurować środowisko

  • Postępuj zgodnie z instrukcjami w tym linku
  • Pobierz zestaw Flutter SDK
  • Uruchom Flutter doctor, aby zainstalować wszystkie zależności
trzepotliwy doktor
  • Użyj poniższego polecenia, aby otworzyć symulator iOS
otwórz - symulator
  • Aby otworzyć emulator Androida, uruchom Android Studio> narzędzia> AVD Manager i wybierz opcję Utwórz urządzenie wirtualne.

Aplikacja Flutter Building

Możesz uzyskać pełny kod źródłowy w linku GitHub na dole posta. Poniżej pokazano, w jaki sposób czerpiemy z przykładowego projektu Flutter, aby uzupełnić kod źródłowy w GitHub.

Krok 1: Utwórz nową wersję demonstracyjną wywoływania projektu trzepotania Uruchom symulator i uruchom projekt za pomocą trzepotania. Możesz użyć Android Studio lub VSCode jako preferowanego IDE. Kroki, aby skonfigurować edytor tutaj.

trzepotanie

Jeśli masz zarówno emulator Androida, jak i symulator iOS, uruchom następujące polecenie, aby wykonać je w obu przypadkach.

trzepotanie -d wszystko

Powinieneś zobaczyć podobne ekrany zarówno w emulatorze Androida, jak i symulatorze iOS.

Po lewej: Android, po prawej: iOS
Jeśli chcesz wiedzieć, jak uzyskać zrzuty ekranu na swoich symulatorach;
W systemie Android: wystarczy kliknąć ikonę kamery po lewej stronie okienka narzędzi. Obraz zostanie zapisany na pulpicie
W systemie iOS: [Opcja 1] Przytrzymaj i naciśnij klawisze Command + Shift + 4. Naciśnij spację, aby zmienić wskaźnik myszy na ikonę aparatu. Wskaż symulator iOS, kliknij, aby zrobić zrzut ekranu. Obraz zostanie zapisany na pulpicie.

[Opcja 2] Wybierz Symulator i naciśnij klawisze Command + S. Dziękujemy JerryZhou za udostępnienie tych informacji.

Krok 2: W main.dart usuń całą zawartość i dodaj następujący plik do pliku. Stworzymy nowy plik o nazwie login_page.dart, który ma klasę LoginPage. Na swoim terminalu naciśnij klawisz R, aby wykonać przeładowanie na gorąco, a powinieneś zobaczyć „Hello World” na ekranie.

Main.dart

import „package: flutter / material.dart”;
import 'login_signup_page.dart';

void main () => runApp (new MyApp ());

klasa MyApp rozszerza StatelessWidget {
  
  @nadpisanie
  Kompilacja widgetów (kontekst BuildContext) {
    zwróć nowy MaterialApp (
      tytuł: „Flutter Login Demo”,
      motyw: nowy ThemeData (
        primarySwatch: Colors.blue,
      ),
      strona główna: nowy LoginSignUpPage ()
    );
  }
}

login_signup_page.dart

import „package: flutter / material.dart”;

klasa LoginSignUpPage rozszerza StatelessWidget {

  @nadpisanie
  Kompilacja widgetów (kontekst BuildContext) {
    zwróć nowe rusztowanie (
      appBar: nowy AppBar (
        tytuł: nowy tekst („Demo logowania Flutter”),
      ),
      body: new Container (
        dziecko: nowy tekst („Hello World”),
      ),
    );
  }
}

Krok 3: Zmiana z bezpaństwowego na stanowy.

login_signup_page.dart

import „package: flutter / material.dart”;

klasa LoginSignUpPage rozszerza StatefulWidget {

  @nadpisanie
  Stan  createState () => new _LoginSignUpPageState ();

}

klasa _LoginSignUpPageState rozszerza stan  {

  @nadpisanie
  Kompilacja widgetów (kontekst BuildContext) {
    zwróć nowe rusztowanie (
      appBar: nowy AppBar (
        tytuł: nowy tekst („Demo logowania Flutter”),
      ),
      body: new Container (
        dziecko: nowy tekst („Hello World”),
      ),
    );
  }
}

Krok 4: Wewnątrz korpusu rusztowania zamieńmy tekst Hello Word na formularz, a wewnątrz niego wstawimy ListView. ListView pobiera tablicę widżetów. Przekomponujemy każdy składnik interfejsu użytkownika do osobnego widżetu.

Ilekroć korzystamy z wprowadzania tekstu, lepiej jest owinąć go wokół ListView, aby uniknąć błędu renderowania, gdy pojawia się miękka klawiatura z powodu przepełnienia pikseli.

login_signup_page.dart

@nadpisanie
Kompilacja widgetów (kontekst BuildContext) {
  _isIos = Theme.of (kontekst) .platform == TargetPlatform.iOS;
  zwróć nowe rusztowanie (
      appBar: nowy AppBar (
        tytuł: nowy tekst („Demo logowania Flutter”),
      ),
      body: Stack (
        dzieci:  [
          _showBody (),
          _showCircularProgress (),
        ],
      ));
}

Krok 5: Budowanie każdego komponentu interfejsu użytkownika

Zauważ, że w ciele Scaffold jako ciało mamy widżet Stack. Zasadniczo chcę pokazać użytkownikowi cykliczny wskaźnik ładowania, gdy uruchomione jest jakiekolwiek działanie związane z logowaniem lub rejestracją. Aby to zrobić, musimy nałożyć wskaźnik CircularProgressIndicator (na szczęście Flutter ma już ten widget, więc aby go użyć, wystarczy go wywołać) z naszym głównym układem widgetów (formularz logowania / rejestracji). Jest to funkcja widżetu Stack, który umożliwia nakładanie jednego widżetu na inny widżet. Aby kontrolować, czy wyświetlać CircularProgressIndicator, czy nie, sprawdzamy bool _isLoading, czy teraz ekran się ładuje, czy nie.

Widżet _showCircularProgress () {
  if (_isLoading) {
    return Center (child: CircularProgressIndicator ());
  } return Container (wysokość: 0,0, szerokość: 0,0);

}

W przypadku logo użyjemy widżetu bohatera, a także zaimportujemy obraz, dodając następujący wiersz w pubspec.yaml. Następnie uruchom pakiety get, aby zaimportować obraz.

majątek:
  - asset / flutter-icon.png

login_signup_page.dart

Widżet _showLogo () {
  zwróć nowego Bohatera (
    tag: „bohater”,
    dziecko: Padding (
      wypełnienie: EdgeInsets.fromLTRB (0,0, 70,0, 0,0, 0,0),
      dziecko: CircleAvatar (
        backgroundColor: Colors.transparent,
        promień: 48,0,
        child: Image.asset ('asset / flutter-icon.png'),
      ),
    ),
  );
}

[Aktualizacja] Wcześniej używaliśmy elastycznego widżetu odstępów za pomocą SizedBox, który pobiera dane o wysokości, aby mieć pionowe odstępy między 2 widżetami. Teraz umieszczamy tylko jeden widżet w widgecie dopełniania i używamy padding: EdgeInsets.fromLTRB (), co oznacza od lewej, góry, prawej i dołu i odpowiednio wpisujemy wartość dopełniania we właściwej pozycji.

Dalej jest pole formularza adresu e-mail i hasła. Uwaga dla każdego pola, które mamy walidator i onSaved. Te 2 wywołania zwrotne zostaną uruchomione po wywołaniu form.validate () i form.save (). Na przykład, jeśli wywoływana jest form.save (), wartość z pola formularza tekstowego jest kopiowana do innej zmiennej lokalnej.

Wprowadzimy również weryfikator do naszych pól, aby sprawdzić, czy dane wejściowe są puste, a następnie pokażemy ostrzeżenie użytkownikowi na czerwono. Musimy także utworzyć zmienne _email i _password do przechowywania wartości. W przypadku hasła ustawiamy obsecureText: true, aby ukryć hasło użytkownika.

Aktualizacja: Dodałem metodę przycinania zarówno do adresu e-mail, jak i hasła, aby usunąć niezamierzone wiodące lub końcowe białe spacje.

Widżet _showEmailInput () {
  zwrot Padding (
    padding: const EdgeInsets.fromLTRB (0,0, 100,0, 0,0, 0,0),
    child: new TextFormField (
      maxLines: 1,
      keyboardType: TextInputType.emailAddress,
      autofocus: false,
      dekoracja: nowy InputDecoration (
          hintText: „E-mail”,
          ikona: nowa ikona (
            Icons.mail,
            kolor: kolory. szary,
          )),
      validator: (value) => value.isEmpty? „E-mail nie może być pusty”: null,
      onSaved: (wartość) => _email = wartość.trim (),
    ),
  );
}

Widżet _showPasswordInput () {
  zwrot Padding (
    padding: const EdgeInsets.fromLTRB (0,0, 15,0, 0,0, 0,0),
    child: new TextFormField (
      maxLines: 1,
      obscureText: true,
      autofocus: false,
      dekoracja: nowy InputDecoration (
          hintText: „Hasło”,
          ikona: nowa ikona (
            Icons.lock,
            kolor: kolory. szary,
          )),
      validator: (value) => value.isEmpty? „Hasło nie może być puste”: null,
      onSaved: (wartość) => _password = wartość.trim (),
    ),
  );
}

Następnie musimy dodać główny przycisk, ale powinien on wyświetlać poprawny tekst w zależności od tego, czy użytkownik chce założyć nowe konto, czy zalogować się na istniejące konto. W tym celu musimy utworzyć wyliczenie, aby śledzić, czy formularz służy do logowania lub rejestracji.

enum FormMode {LOGIN, SIGNUP}

Przydzielimy metodę dla funkcji wywołania zwrotnego przycisku. W tym celu utworzymy metodę o nazwie _validateAndSubmit, która przekaże zarówno e-mail, jak i hasło do uwierzytelnienia Firebase. Więcej na ten temat w dalszej części tego postu.

Widżet _showPrimaryButton () {
  zwróć nowy Padding (
      wypełnienie: EdgeInsets.fromLTRB (0,0, 45,0, 0,0, 0,0),
      child: new MaterialButton (
        wysokość: 5.0,
        minWidth: 200,0,
        wysokość: 42,0,
        kolor: Kolory. niebieski,
        child: _formMode == FormMode.LOGIN
            ? nowy tekst („Logowanie”,
                styl: nowy TextStyle (fontSize: 20.0, kolor: Colors.white))
            : nowy tekst („Utwórz konto”,
                styl: nowy TextStyle (fontSize: 20.0, kolor: Colors.white)),
        onPressed: _validateAndSubmit,
      ));
}

Teraz musimy dodać dodatkowy przycisk, aby użytkownik mógł przełączać się między formularzem rejestracji i logowania. W metodzie onPressed chcielibyśmy przełączać stan formularza pomiędzy LOGIN i SIGNUP. Uwaga dla dodatkowego przycisku, używamy FlatButton zamiast RaisedButton, podobnie jak poprzedni przycisk przesyłania. Powodem jest to, że jeśli masz 2 przyciski i chciałbyś, aby jeden był bardziej charakterystyczny niż drugi, RaisedButton jest właściwym wyborem, ponieważ natychmiast przyciąga uwagę użytkowników w porównaniu do FlatButton.

login_page.dart

Widżet _showSecondaryButton () {
  zwróć nowy FlatButton (
    child: _formMode == FormMode.LOGIN
        ? nowy tekst („Utwórz konto”,
            styl: nowy TextStyle (fontSize: 18.0, fontWeight: FontWeight.w300))
        : nowy tekst („Masz konto? Zaloguj się”,
            styl:
                nowy TextStyle (fontSize: 18.0, fontWeight: FontWeight.w300)),
    onPressed: _formMode == FormMode.LOGIN
        ? _changeFormToSignUp
        : _changeFormToLogin,
  );
}

W metodzie przełączania trybu formularza kluczowe jest owinięcie go wokół setState, ponieważ musimy powiedzieć Flutterowi, aby ponownie renderował ekran ze zaktualizowaną wartością FormMode.

void _changeFormToSignUp () {
  _formKey.currentState.reset ();
  _errorMessage = "";
  setState (() {
    _formMode = FormMode.SIGNUP;
  });
}

void _changeFormToLogin () {
  _formKey.currentState.reset ();
  _errorMessage = "";
  setState (() {
    _formMode = FormMode.LOGIN;
  });
}

Następnie będziemy mieli funkcję _showErrorMessage (), która przekazuje komunikat o błędzie użytkownikowi po stronie Firebase, gdy próbują zalogować się lub zarejestrować. Ten komunikat o błędzie może przypominać „Istnieje już konto użytkownika”. Będziemy mieć String _errorMessage do przechowywania komunikatu o błędzie z Firebase.

Widżet _showErrorMessage () {
  if (_errorMessage.length> 0 && _errorMessage! = null) {
    zwróć nowy tekst (
      _Komunikat o błędzie,
      styl: TextStyle (
          fontSize: 13,0,
          kolor: Colors.red,
          wysokość: 1,0,
          fontWeight: FontWeight.w300),
    );
  } else {
    zwróć nowy pojemnik (
      wysokość: 0,0,
    );
  }
}

Na koniec uporządkujmy poszczególne komponenty interfejsu użytkownika i przywróćmy je do naszego ListView.

Widżet _showBody () {
  zwróć nowy pojemnik (
      padding: EdgeInsets.all (16.0),
      dziecko: nowy formularz (
        klucz: _formKey,
        dziecko: nowy ListView (
          shrinkWrap: true,
          dzieci:  [
            _showLogo (),
            _showEmailInput (),
            _showPasswordInput (),
            _showPrimaryButton (),
            _showSecondaryButton (),
            _showErrorMessage (),
          ],
        ),
      ));
}
Walidator TextFormField w akcji

Krok 6: Zarejestruj nowy projekt w Firebase

Wejdź na https://console.firebase.google.com i zarejestruj nowy projekt.

W systemie Android kliknij ikonę Androida. Wpisz nazwę swojego pakietu, która znajduje się w Android / app / src / main / AndroidManifest.xml

Pobierz plik konfiguracyjny to google-services.json (Android).

Przeciągnij plik google-services.json do folderu aplikacji w widoku projektu

Musimy dodać wtyczkę Google Services Gradle, aby odczytać google-services.json. W /android/app/build.gradle dodaj następujący kod do ostatniego wiersza pliku.

zastosuj wtyczkę: „com.google.gms.google-services”

W Android / build.gradle, wewnątrz tagu buildscript, dodaj nową zależność.

buildscript {
   repozytoria {
      // ...
}
zależności {
   // ...
   classpath „com.google.gms: google-services: 3.2.1”
}

W systemie iOS otwórz ios / Runner.xcworkspace, aby uruchomić Xcode. Nazwę pakietu można znaleźć w identyfikatorze pakietu w widoku Runner.

Pobierz plik konfiguracyjny, którym jest GoogleService-info.plist (iOS).

Przeciągnij GoogleService-info.plist do podfolderu Runner w Runner, jak pokazano poniżej.

7 Krok 7: dodaj zależności w pubspec.yaml
Następnie musimy dodać zależność firebase_auth w pubspec.yaml. Aby uzyskać najnowszy numer wersji, przejdź na stronę https://pub.dartlang.org/ i wyszukaj uwierzytelnianie firebase.

firebase_auth: ^ 0.6.6

Krok 8: Importuj uwierzytelnianie Firebase

import 'package: firebase_auth / firebase_auth.dart';

Krok 9: Włącz rejestrację przy użyciu adresu e-mail i hasła w Firebase

Krok 10: Zaloguj się do Firebase

Firebase signInWithEmailAndPassword to metoda zwracająca przyszłą wartość. Dlatego metoda musi poczekać, a funkcja zewnętrznego opakowania musi mieć asynchronię. Dlatego dołączamy metody logowania i rejestracji za pomocą try catch block. Jeśli wystąpił błąd, nasz blok catch powinien być w stanie przechwycić komunikat o błędzie i wyświetlić go użytkownikowi.

Istnieje różnica w sposobie przechowywania wiadomości w błędzie zgłaszanym przez Firebase. W IOS wiadomość jest w e.details, podczas gdy w Androidzie jest w e.message. Możesz łatwo sprawdzić platformę, używając _isIos = Theme.of (kontekst) .platform == TargetPlatform.iOS i powinna ona znajdować się w dowolnej metodzie widgetu kompilacji, ponieważ potrzebuje kontekstu.

_validateAndSubmit () async {
  setState (() {
    _errorMessage = "";
    _isLoading = true;
  });
  if (_validateAndSave ()) {
    Ciąg userId = "";
    próbować {
      if (_formMode == FormMode.LOGIN) {
        userId = czekaj na widget.auth.signIn (_email, _password);
        print („Zalogowano: $ userId”);
      } else {
        userId = czekaj na widget.auth.signUp (_email, _password);
        print („Zarejestrowany użytkownik: $ userId”);
      }
      if (userId.length> 0 && userId! = null) {
        widget.onSignedIn ();
      }
    } catch (e) {
      print („Błąd: $ e”);
      setState (() {
        _isLoading = false;
        if (_isIos) {
          _errorMessage = e.details;
        } else
          _errorMessage = e.message;
      });
    }
  }
}

Krok 11: Wyczyść pole formularza po przełączeniu

Musimy dodać następujący wiersz zarówno w _changeFormToSignUp, jak i _changeFormToLogin, aby zresetować pole formularza za każdym razem, gdy użytkownik przełącza się między formularzem logowania i rejestracji.

formKey.currentState.reset ();

Krok 12: Spróbuj zarejestrować użytkownika

Spróbujmy zarejestrować użytkownika, wprowadzając adres e-mail i hasło.

Jeśli napotkasz coś takiego jak poniżej, dzieje się tak, ponieważ na końcu wiadomości e-mail jest więcej odstępów
I / flutter (14294): Błąd PlatformException (wyjątek, adres e-mail jest źle sformatowany., Null)
Jeśli napotkasz coś takiego jak poniżej, zmień hasło na co najmniej 6 znaków.
I / flutter (14294): Błąd PlatformException (wyjątek, Podane hasło jest nieprawidłowe. [Hasło powinno mieć co najmniej 6 znaków], null)

Wreszcie po sukcesie powinieneś zobaczyć w swoim terminalu następującą linię. Ciąg losowy jest identyfikatorem użytkownika.

I / flutter (14294): Zarejestrowano JSwpKsCFxPZHEqeuIO4axCsmWuP2

Podobnie, jeśli spróbujemy zalogować się do tego samego użytkownika, którego się zarejestrowaliśmy, powinniśmy otrzymać coś takiego:

I / flutter (14294): Podpisano w JSwpKsCFxPZHEqeuIO4axCsmWuP2

Krok 13: Zaimplementuj klasę Auth

Utwórz nowe uwierzytelnianie wywołania pliku. Dart. Zamierzamy również zaimplementować klasę abstrakcyjną BaseAuth. Celem tej klasy abstrakcyjnej jest to, że działa ona jako warstwa pośrednia między naszymi komponentami interfejsu użytkownika a rzeczywistą klasą implementacji, która zależy od wybranego przez nas frameworka. W każdym razie postanowiliśmy zamienić Firebase na coś takiego jak PostgreSQL, wtedy nie będzie to miało wpływu na składniki interfejsu użytkownika.

import „dart: async”;
import 'package: firebase_auth / firebase_auth.dart';

klasa abstrakcyjna BaseAuth {
  Przyszłe logowanie  (ciąg adresu e-mail, hasło ciągu);
  Future  signUp (ciąg wiadomości e-mail, hasło ciągu);
  Future  getCurrentUser ();
  Przyszłe  signOut ();
}

klasa Auth implementuje BaseAuth {
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

  Przyszłe logowanie  (ciąg adresu e-mail, hasło ciągu) asynchronizuje {
    FirebaseUser user = czekaj _firebaseAuth.signInWithEmailAndPassword (email: email, hasło: hasło);
    return user.uid;
  }

  Future  signUp (ciąg adresu e-mail, hasło ciągu) asynchronizuje {
    Użytkownik FirebaseUser = oczekuje na _firebaseAuth.createUserWithEmailAndPassword (e-mail: e-mail, hasło: hasło);
    return user.uid;
  }

  Future  getCurrentUser () async {
    FirebaseUser user = czekaj _firebaseAuth.currentUser ();
    return user.uid;
  }

  Przyszłe  signOut () async {
    return _firebaseAuth.signOut ();
  }
}

W login_page.dart

klasa LoginSignUpPage rozszerza StatefulWidget {
LoginSignUpPage ({this.auth});
końcowe uwierzytelnianie BaseAuth;
@nadpisanie
Stan  createState () => new _LoginPageState ();
}

W main.dart

strona główna: nowy LoginSignUpPage (auth: new Auth ())

Z powrotem w login_page.dart, zamieńmy nasze signInWithEmailAndPassword

Ciąg userId = oczekiwanie na widget.auth.signIn (_email, _password);
Ciąg userId = oczekiwanie na widget.auth.signUp (_email, _password);

Krok 14: Rootuj i wracaj do domu dzięki VoidCallback

Utwórzmy nowy plik call home_page.dart. Zostanie wyświetlona lista pustych czynności do wykonania po pomyślnym zalogowaniu lub rejestracji użytkownika. Jak zwykle implementujemy Scaffold z AppBar, ale tym razem będziemy mieć FlatButton w AppBar dla funkcji wylogowania. To wylogowanie wywołuje metodę wylogowania Firebase wewnątrz klasy BaseAuth.

Musimy również utworzyć wywołanie pliku root_page.dart. Zastąpi to home: LoginSignUpPage (auth: new Auth ()) w naszym main.dart.

home: nowy RootPage (auth: new Auth ())

Po uruchomieniu aplikacja powinna przejść do tej strony. Ta strona działa jak menedżer, aby sprawdzić poprawność identyfikatora użytkownika Firebase i przekierowuje go na odpowiednią stronę. Na przykład, jeśli identyfikator użytkownika jest obecny, co oznacza, że ​​użytkownik jest już zalogowany i użytkownik powinien wyświetlić stronę domową zamiast strony login_signup_page. Zostanie to wykonane wewnątrz initState, czyli funkcji, która zostanie najpierw wykonana w pliku.

Na stronie root_page będą 2 metody: _onLoggedIn i _onSignedOut. W _onLoggedIn staramy się uzyskać identyfikator użytkownika i sethate authStatus dla użytkownika jest już zalogowany. W _onSignedOut usuwamy zapisany id użytkownika i setstate authStatus dla użytkownika nie jest zalogowany.

W root_page przekazujemy 2 parametry do login_page, jeden to klasa Auth, którą implementujemy łatwiej (tworzymy ją na main.dart) i _onLoggedIn). Na stronie login_signup tworzymy 2 zmienne, które są autorami typu BaseAuth i onSignedIn typu VoidCallback. Możemy łatwo pobrać 2 parametry przekazane na stronę login_signup_page do naszych zmiennych lokalnych za pomocą następującego wiersza.

LoginSignUpPage ({this.auth, this.onSignedIn});

końcowe uwierzytelnianie BaseAuth;
final VoidCallback onSignedIn;

VoidCallback umożliwia wywołanie metody login_signup_page w celu wywołania metody wewnątrz root_page, którą jest _onSignedIn, gdy użytkownik się zaloguje. Gdy wywoływane jest _onSignedIn, ustawi authStatus na LOGGED_IN i ustawiState na przerysowanie aplikacji. Gdy aplikacja jest przerysowana, initState sprawdza authStatus, a ponieważ jest to LOGGED_IN, wyświetli stronę domową, przekazując auth i voidcallback z _signOut.

root_page.dart

@nadpisanie
Kompilacja widgetów (kontekst BuildContext) {
  przełącznik (authStatus) {
    przypadek AuthStatus.NOT_DETERMINED:
      return _buildWaitingScreen ();
      przerwa;
    sprawa AuthStatus.NOT_LOGGED_IN:
      zwróć nowy LoginSignUpPage (
        auth: widget.auth,
        onSignedIn: _onLoggedIn,
      );
      przerwa;
    przypadek AuthStatus.LOGGED_IN:
      if (_userId.length> 0 && _userId! = null) {
        zwróć nową stronę główną (
          userId: _userId,
          auth: widget.auth,
          onSignedOut: _onSignedOut,
        );
      } else return _buildWaitingScreen ();
      przerwa;
    domyślna:
      return _buildWaitingScreen ();
  }
}

Zwróć uwagę na wstążkę debugującą w prawym górnym rogu aplikacji, możesz ją łatwo usunąć, dodając następujący wiersz w widżecie MaterialApp w main.dart

Ekran logowania do wersji demonstracyjnej
debugShowCheckedModeBanner: false,
Usunięto baner debugowania

Możesz uzyskać pełny kod źródłowy w linku github poniżej

Jeśli uznasz, że ten artykuł jest przydatny, podaj

Odniesienie:

Flutter Pub to średnia publikacja, która zawiera najnowsze i niesamowite zasoby, takie jak artykuły, filmy, kody, podcasty itp. Na temat tej wspaniałej technologii, aby nauczyć Cię, jak tworzyć z nią piękne aplikacje. Możesz nas znaleźć na Facebooku, Twitterze i medium lub dowiedzieć się więcej o nas tutaj. Chcielibyśmy się połączyć! A jeśli jesteś pisarzem zainteresowanym pisaniem dla nas, możesz to zrobić za pomocą tych wytycznych.