استفاده از احراز هویت فایربیس با فلاتر — از صفر تا صد

۴۶۷ بازدید
آخرین به‌روزرسانی: ۲۹ شهریور ۱۴۰۲
زمان مطالعه: ۱۰ دقیقه
استفاده از احراز هویت فایربیس با فلاتر — از صفر تا صد

در این مقاله شیوه ایجاد یک اپلیکیشن با فلاتر را شرح داده و اتصال آن به سیستم احراز هویت فایربیس را مورد بررسی قرار می‌دهیم. قصد ما این است که با فایربیس تعامل پیدا کنیم تا هویت کاربر را احراز کرده و تابع‌های دیگری را نیز در فایربیس اجرا کنیم. در این راهنما می‌توانید یک اپلیکیشن ساده فلاتر بسازید که در آن کاربر می‌تواند از طریق اپلیکیشن ثبت نام کرده و در آن لاگین کند. اگر کاربر تمایل داشته باشد، می‌تواند ایمیل و رمز عبور را تغییر دهد و یا حتی حساب کاربری را حذف کند.

اهداف

احراز هویت فایربیس با فلاتر

اهداف این پروژه شامل موارد زیر هستند:

  • پیکربندی فایربیس روی پروژه فلاتر
  • ایجاد فرم‌های ثبت نام، لاگین و دیگر کارکردها در فایربیس

روش اجرای پروژه

در این بخش و همانطور که از عنوان بر می‌آید، روش اجرای پروژه را با هم مرور می‌کنیم.

گام 1

قبل از هر چیز باید یک پروژه فلاتر ایجاد کنیم. اگر نمی‌دانید چگونه باید پروژه فلاتر ایجاد کنید، می‌توانید از این راهنمای مجله فرادرس کمک بگیرید:

پس از ایجاد پروژه فلاتر باید فایربیس را روی پروژه پیکربندی کنیم. در مورد اندروید به کنسول فایربیس بروید و روی دکمه «افزودن اپلیکیشن» (Add App) کلیک کنید تا با انتخاب آیکون اندروید فرمی مانند زیر نمایش یابد:

احراز هویت فایربیس با فلاتر

نام پروژه را اضافه کنید. با باز کردن فایل AndroidManifest در مسیر android/app/src/main/AndroidManifest.xml می‌توانید نام پروژه را به دست آورید. پس از آن فایل google-services.json را دانلود کنید. سپس به پروژه بروید و فایل google-services.json را درون پوشه دایرکتوری اندروید یعنی android/app قرار دهید.

باید افزونه Google Services Gradle را نیز برای خواندن فایل Google Services Gradle اضافه کنیم. بنابراین فایل build.gradle را به صورت زیر ویرایش کنید:

احراز هویت فایربیس با فلاتر

پس از پایان یافتن ویرایش‌ها پروژه را همگام‌سازی (Sync) کنید.

در مورد iOS، برای اجرای Xcode ابتدا ios/Runner.xcworkspace را باز کنید. نام پکیج را می‌توانید در شناسه bundle در نمای Runner ببینید. فایل config را که به صورت GoogleService-info.plist است دانلود کنید. این فایل را درون زیرپوشه Runner درون Runner که به صورت زیر است، بکشید:

احراز هویت فایربیس با فلاتر

سپس به کنسول فایربیس بروید و روی دکمه احراز هویت در سمت چپ نوار ناوبری بزنید. سپس ایمیل/رمز عبور را فعال کنید. با این فعال‌سازی می‌توانید کاربران را در فایربیس ثبت نام کنید.

احراز هویت فایربیس با فلاتر

اکنون پیکربندی فایربیس انجام یافته است. کار بعدی که باید انجام دهیم در سطح کد است.

گام 2

در این بخش باید وابستگی‌ها را به پروژه فلاتر خود اضافه کنیم. به این منظور به فایل pubspec.yaml بروید و زیر وابستگی‌ها خط زیر را اضافه کنید:

firebase_auth: ^0.9.0

پروژه را ذخیره کنید.

گام 3

اکنون باید سرویس‌هایی که به اپلیکیشن موبایل با فایربیس وصل می‌شوند را بنویسیم. درون پوشه lib یک پوشه جدید به نام Services ایجاد می‌کنیم. سپس یک فایل dart درون پوشه Services به نام authentication.dart ایجاد کرده و کد زیر را در آن قرار می‌دهیم:

1import 'dart:async';
2import 'package:firebase_auth/firebase_auth.dart';
3
4abstract class BaseAuth {
5  Future<String> signIn(String email, String password);
6
7  Future<String> signUp(String email, String password);
8
9  Future<FirebaseUser> getCurrentUser();
10
11  Future<void> sendEmailVerification();
12
13  Future<void> signOut();
14
15  Future<bool> isEmailVerified();
16
17  Future<void> changeEmail(String email);
18
19  Future<void> changePassword(String password);
20
21  Future<void> deleteUser();
22
23  Future<void> sendPasswordResetMail(String email);
24}
25
26class Auth implements BaseAuth {
27  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
28
29  Future<String> signIn(String email, String password) async {
30    FirebaseUser user = await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
31    return user.uid;
32  }
33
34  Future<String> signUp(String email, String password) async {
35    FirebaseUser user = await _firebaseAuth.createUserWithEmailAndPassword(
36        email: email, password: password);
37    return user.uid;
38  }
39
40  Future<FirebaseUser> getCurrentUser() async {
41    FirebaseUser user = await _firebaseAuth.currentUser();
42    return user;
43  }
44
45  Future<void> signOut() async {
46    return _firebaseAuth.signOut();
47  }
48
49  Future<void> sendEmailVerification() async {
50    FirebaseUser user = await _firebaseAuth.currentUser();
51    user.sendEmailVerification();
52  }
53
54  Future<bool> isEmailVerified() async {
55    FirebaseUser user = await _firebaseAuth.currentUser();
56    return user.isEmailVerified;
57  }
58
59  @override
60  Future<void> changeEmail(String email) async {
61    FirebaseUser user = await _firebaseAuth.currentUser();
62    user.updateEmail(email).then((_) {
63      print("Succesfull changed email");
64    }).catchError((error) {
65      print("email can't be changed" + error.toString());
66    });
67    return null;
68  }
69
70  @override
71  Future<void> changePassword(String password) async {
72    FirebaseUser user = await _firebaseAuth.currentUser();
73    user.updatePassword(password).then((_) {
74      print("Succesfull changed password");
75    }).catchError((error) {
76      print("Password can't be changed" + error.toString());
77    });
78    return null;
79  }
80
81  @override
82  Future<void> deleteUser() async {
83    FirebaseUser user = await _firebaseAuth.currentUser();
84    user.delete().then((_) {
85      print("Succesfull user deleted");
86    }).catchError((error) {
87      print("user can't be delete" + error.toString());
88    });
89    return null;
90  }
91
92  @override
93  Future<void> sendPasswordResetMail(String email) async{
94    await _firebaseAuth.sendPasswordResetEmail(email: email);
95    return null;
96  }
97
98}

در کد فوق، یک کلاس به نام BaseAuth ایجاد می‌کنیم تا متدی که قصد داریم پیاده‌سازی کنیم را بنویسیم و پارامترها را ارسال کنیم. سپس یک کلاس مجزا به نام Auth ایجاد می‌کنیم آن را در کلاس BaseAuth پیاده‌سازی می‌کنیم به طوری که متدهای الحاق یافته بتوانند در Auth پیاده‌سازی شوند.

گام 4

در این گام باید صفحه‌های ثبت نام و لاگین کاربر را طراحی کنیم. یک پوشه درون دایرکتوری lib به نام pages ایجاد کنید. درون پوشه pages یک فایل دارت به نام login_signup_page.dart ایجاد کرده و کد دارت زیر را در آن بنویسید:

1import 'package:flutter/material.dart';
2import '../services/authentication.dart';
3
4class LoginSignUpPage extends StatefulWidget {
5  LoginSignUpPage({this.auth, this.onSignedIn});
6
7  final BaseAuth auth;
8  final VoidCallback onSignedIn;
9
10  @override
11  State<StatefulWidget> createState() => new _LoginSignUpPageState();
12}
13
14enum FormMode { LOGIN, SIGNUP }
15
16class _LoginSignUpPageState extends State<LoginSignUpPage> {
17  final _formKey = new GlobalKey<FormState>();
18
19  String _email;
20  String _password;
21  String _errorMessage;
22
23  // Initial form is login form
24  FormMode _formMode = FormMode.LOGIN;
25  bool _isIos;
26  bool _isLoading;
27
28  // Check if form is valid before perform login or signup
29  bool _validateAndSave() {
30    final form = _formKey.currentState;
31    if (form.validate()) {
32      form.save();
33      return true;
34    }
35    return false;
36  }
37
38  // Perform login or signup
39  void _validateAndSubmit() async {
40    setState(() {
41      _errorMessage = "";
42      _isLoading = true;
43    });
44    if (_validateAndSave()) {
45      String userId = "";
46      try {
47        if (_formMode == FormMode.LOGIN) {
48          userId = await widget.auth.signIn(_email, _password);
49          print('Signed in: $userId');
50        } else {
51          userId = await widget.auth.signUp(_email, _password);
52          widget.auth.sendEmailVerification();
53          _showVerifyEmailSentDialog();
54          print('Signed up user: $userId');
55        }
56        setState(() {
57          _isLoading = false;
58        });
59
60        if (userId.length > 0 && userId != null && _formMode == FormMode.LOGIN) {
61          widget.onSignedIn();
62        }
63
64      } catch (e) {
65        print('Error: $e');
66        setState(() {
67          _isLoading = false;
68          if (_isIos) {
69            _errorMessage = e.details;
70          } else
71            _errorMessage = e.message;
72        });
73      }
74    }
75  }
76
77
78  @override
79  void initState() {
80    _errorMessage = "";
81    _isLoading = false;
82    super.initState();
83  }
84
85  void _changeFormToSignUp() {
86    _formKey.currentState.reset();
87    _errorMessage = "";
88    setState(() {
89      _formMode = FormMode.SIGNUP;
90    });
91  }
92
93  void _changeFormToLogin() {
94    _formKey.currentState.reset();
95    _errorMessage = "";
96    setState(() {
97      _formMode = FormMode.LOGIN;
98    });
99  }
100
101  @override
102  Widget build(BuildContext context) {
103    _isIos = Theme.of(context).platform == TargetPlatform.iOS;
104    return new Scaffold(
105        appBar: new AppBar(
106          title: new Text('Flutter Firebase Authentication'),
107        ),
108        body: Stack(
109          children: <Widget>[
110            _showBody(),
111            _showCircularProgress(),
112          ],
113        ));
114  }
115
116  Widget _showCircularProgress(){
117    if (_isLoading) {
118      return Center(child: CircularProgressIndicator());
119    } return Container(height: 0.0, width: 0.0,);
120
121  }
122
123  void _showVerifyEmailSentDialog() {
124    showDialog(
125      context: context,
126      builder: (BuildContext context) {
127        // return object of type Dialog
128        return AlertDialog(
129          title: new Text("Verify your account"),
130          content: new Text("Link to verify account has been sent to your email"),
131          actions: <Widget>[
132            new FlatButton(
133              child: new Text("Dismiss"),
134              onPressed: () {
135                _changeFormToLogin();
136                Navigator.of(context).pop();
137              },
138            ),
139          ],
140        );
141      },
142    );
143  }
144
145  Widget _showBody(){
146    return new Container(
147        padding: EdgeInsets.all(16.0),
148        child: new Form(
149          key: _formKey,
150          child: new ListView(
151            shrinkWrap: true,
152            children: <Widget>[
153              _showLogo(),
154              _showEmailInput(),
155              _showPasswordInput(),
156              _showPrimaryButton(),
157              _showSecondaryButton(),
158              _showErrorMessage(),
159            ],
160          ),
161        ));
162  }
163
164  Widget _showErrorMessage() {
165    if (_errorMessage.length > 0 && _errorMessage != null) {
166      return new Text(
167        _errorMessage,
168        style: TextStyle(
169            fontSize: 13.0,
170            color: Colors.red,
171            height: 1.0,
172            fontWeight: FontWeight.w300),
173      );
174    } else {
175      return new Container(
176        height: 0.0,
177      );
178    }
179  }
180
181  Widget _showLogo() {
182    return new Hero(
183      tag: 'hero',
184      child: Padding(
185        padding: EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 0.0),
186        child: CircleAvatar(
187          backgroundColor: Colors.transparent,
188          radius: 48.0,
189          child: Image.asset('assets/images/logo.png'),
190        ),
191      ),
192    );
193  }
194
195  Widget _showEmailInput() {
196    return Padding(
197      padding: const EdgeInsets.fromLTRB(0.0, 100.0, 0.0, 0.0),
198      child: new TextFormField(
199        maxLines: 1,
200        keyboardType: TextInputType.emailAddress,
201        autofocus: false,
202        decoration: new InputDecoration(
203            hintText: 'Email',
204            icon: new Icon(
205              Icons.mail,
206              color: Colors.grey,
207            )),
208        validator: (value) => value.isEmpty ? 'Email can\'t be empty' : null,
209        onSaved: (value) => _email = value.trim(),
210      ),
211    );
212  }
213
214  Widget _showPasswordInput() {
215    return Padding(
216      padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
217      child: new TextFormField(
218        maxLines: 1,
219        obscureText: true,
220        autofocus: false,
221        decoration: new InputDecoration(
222            hintText: 'Password',
223            icon: new Icon(
224              Icons.lock,
225              color: Colors.grey,
226            )),
227        validator: (value) => value.isEmpty ? 'Password can\'t be empty' : null,
228        onSaved: (value) => _password = value.trim(),
229      ),
230    );
231  }
232
233 
234
235  Widget _showSecondaryButton() {
236    return new FlatButton(
237      child: _formMode == FormMode.LOGIN
238          ? new Text('Create an account',
239              style: new TextStyle(fontSize: 18.0, fontWeight: FontWeight.w300))
240          : new Text('Have an account? Sign in',
241              style:
242                  new TextStyle(fontSize: 18.0, fontWeight: FontWeight.w300)),
243      onPressed: _formMode == FormMode.LOGIN
244          ? _changeFormToSignUp
245          : _changeFormToLogin,
246    );
247  }
248
249  Widget _showPrimaryButton() {
250    return new Padding(
251        padding: EdgeInsets.fromLTRB(0.0, 45.0, 0.0, 0.0),
252        child: SizedBox(
253          height: 40.0,
254          child: new RaisedButton(
255            elevation: 5.0,
256            shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(30.0)),
257            color: Colors.blue,
258            child: _formMode == FormMode.LOGIN
259                ? new Text('Login',
260                    style: new TextStyle(fontSize: 20.0, color: Colors.white))
261                : new Text('Create account',
262                    style: new TextStyle(fontSize: 20.0, color: Colors.white)),
263            onPressed: _validateAndSubmit,
264          ),
265        ));
266  }
267  
268}

در این کد برای هر دو صفحه ثبت نام و ورود، از صفحه یکسانی استفاده کرده‌ایم. اما UI آن‌ها متفاوت است.

سپس یک فایل به نام home_page.dart ایجاد می‌کنیم. در این صفحه اصلی، فعالیت‌های زیر انجام خواهند یافت:

  • تغییر رمز عبور کاربر
  • تغییر ایمیل کاربر
  • ارسال ایمیل تأیید حساب به کاربر
  • حذف کاربر
  • خروج از حساب کاربری
1import 'package:flutter/material.dart';
2import '../services/authentication.dart';
3import 'package:firebase_database/firebase_database.dart';
4import 'dart:async';
5
6class HomePage extends StatefulWidget {
7  HomePage({Key key, this.auth, this.userId, this.onSignedOut})
8      : super(key: key);
9
10  final BaseAuth auth;
11  final VoidCallback onSignedOut;
12  final String userId;
13
14  @override
15  State<StatefulWidget> createState() => new _HomePageState();
16}
17
18class _HomePageState extends State<HomePage> {
19
20  final FirebaseDatabase _database = FirebaseDatabase.instance;
21  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
22
23  final TextEditingController _emailFilter = new TextEditingController();
24  final TextEditingController _passwordFilter = new TextEditingController();
25  final TextEditingController _resetPasswordEmailFilter =
26      new TextEditingController();
27
28  String _email = "";
29  String _password = "";
30  String _resetPasswordEmail = "";
31
32  String _errorMessage;
33  bool _isIos;
34  bool _isLoading;
35
36  _HomePageState() {
37    _emailFilter.addListener(_emailListen);
38    _passwordFilter.addListener(_passwordListen);
39    _resetPasswordEmailFilter.addListener(_resetPasswordEmailListen);
40  }
41
42  void _resetPasswordEmailListen() {
43    if (_resetPasswordEmailFilter.text.isEmpty) {
44      _resetPasswordEmail = "";
45    } else {
46      _resetPasswordEmail = _resetPasswordEmailFilter.text;
47    }
48  }
49
50  void _emailListen() {
51    if (_emailFilter.text.isEmpty) {
52      _email = "";
53    } else {
54      _email = _emailFilter.text;
55    }
56  }
57
58  void _passwordListen() {
59    if (_passwordFilter.text.isEmpty) {
60      _password = "";
61    } else {
62      _password = _passwordFilter.text;
63    }
64  }
65
66  final _textEditingController = TextEditingController();
67
68  StreamSubscription<Event> _onTodoAddedSubscription;
69  StreamSubscription<Event> _onTodoChangedSubscription;
70
71  Query _todoQuery;
72
73  bool _isEmailVerified = false;
74
75  @override
76  void initState() {
77    super.initState();
78    _checkEmailVerification();
79  }
80
81  void _checkEmailVerification() async {
82    _isEmailVerified = await widget.auth.isEmailVerified();
83    if (!_isEmailVerified) {
84      _showVerifyEmailDialog();
85    }
86  }
87
88  void _resentVerifyEmail() {
89    widget.auth.sendEmailVerification();
90    _showVerifyEmailSentDialog();
91  }
92
93  void _showVerifyEmailDialog() {
94    showDialog(
95      context: context,
96      builder: (BuildContext context) {
97        // return object of type Dialog
98        return AlertDialog(
99          title: new Text("Verify your account"),
100          content: new Text("Please verify account in the link sent to email"),
101          actions: <Widget>[
102            new FlatButton(
103              child: new Text("Resent link"),
104              onPressed: () {
105                Navigator.of(context).pop();
106                _resentVerifyEmail();
107              },
108            ),
109            new FlatButton(
110              child: new Text("Dismiss"),
111              onPressed: () {
112                Navigator.of(context).pop();
113              },
114            ),
115          ],
116        );
117      },
118    );
119  }
120
121  void _showVerifyEmailSentDialog() {
122    showDialog(
123      context: context,
124      builder: (BuildContext context) {
125        // return object of type Dialog
126        return AlertDialog(
127          title: new Text("Verify your account"),
128          content:
129              new Text("Link to verify account has been sent to your email"),
130          actions: <Widget>[
131            new FlatButton(
132              child: new Text("Dismiss"),
133              onPressed: () {
134                Navigator.of(context).pop();
135              },
136            ),
137          ],
138        );
139      },
140    );
141  }
142
143  @override
144  void dispose() {
145    _onTodoAddedSubscription.cancel();
146    _onTodoChangedSubscription.cancel();
147    super.dispose();
148  }
149
150  
151
152  _signOut() async {
153    try {
154      await widget.auth.signOut();
155      widget.onSignedOut();
156    } catch (e) {
157      print(e);
158    }
159  }
160
161
162  Widget _showButtonList() {
163    return new Container(
164      padding: EdgeInsets.all(26.0),
165      child: new ListView(
166        children: <Widget>[
167          _showChangeEmailContainer(),
168          new SizedBox(
169            height: 40.0,
170          ),
171          _showChangePasswordContainer(),
172          new SizedBox(
173            height: 40.0,
174          ),
175          _showSentResetPasswordEmailContainer(),
176          new SizedBox(
177            height: 40.0,
178          ),
179          _removeUserContainer(),
180        ],
181      ),
182    );
183  }
184
185  @override
186  Widget build(BuildContext context) {
187    return new Scaffold(
188      appBar: new AppBar(
189        title: new Text('Flutter login demo'),
190        actions: <Widget>[
191          new FlatButton(
192              child: new Text('Logout',
193                  style: new TextStyle(fontSize: 17.0, color: Colors.white)),
194              onPressed: _signOut)
195        ],
196      ),
197      body: _showButtonList(),
198    );
199  }
200
201  Widget _showEmailChangeErrorMessage() {
202    if (_errorMessage != null) {
203      return new Text(
204        _errorMessage,
205        style: TextStyle(
206            fontSize: 13.0,
207            color: Colors.red,
208            height: 1.0,
209            fontWeight: FontWeight.w300),
210      );
211    } else {
212      return new Container(
213        height: 0.0,
214      );
215    }
216  }
217
218  _showChangeEmailContainer() {
219    return Container(
220      decoration: BoxDecoration(
221        borderRadius: new BorderRadius.circular(30.0),
222        color: Colors.amberAccent,
223      ),
224      padding: EdgeInsets.fromLTRB(10, 20, 10, 20),
225      child: Column(
226        children: <Widget>[
227          new TextFormField(
228            controller: _emailFilter,
229            decoration: new InputDecoration(
230              contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
231              hintText: "Enter New Email",
232              border:
233                  OutlineInputBorder(borderRadius: BorderRadius.circular(22.0)),
234            ),
235          ),
236          new MaterialButton(
237            shape: RoundedRectangleBorder(
238                borderRadius: new BorderRadius.circular(30.0)),
239            onPressed: () {
240              // widget.auth.changeEmail("abc@gmail.com");
241              _changeEmail();
242            },
243            minWidth: MediaQuery.of(context).size.width,
244            padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
245            color: Colors.blueAccent,
246            textColor: Colors.white,
247            child: Text(
248              "Change Email",
249              textAlign: TextAlign.center,
250            ),
251          ),
252        ],
253      ),
254    );
255  }
256
257  void _changeEmail() {
258    if (_email != null && _email.isNotEmpty) {
259      try {
260        print("============>" + _email);
261        widget.auth.changeEmail(_email);
262      } catch (e) {
263        print("============>" + e);
264        setState(() {
265          _isLoading = false;
266          if (_isIos) {
267            _errorMessage = e.details;
268          } else
269            _errorMessage = e.message;
270        });
271      }
272    } else {
273      print("email feild empty");
274    }
275  }
276
277  void _changePassword() {
278    if (_password != null && _password.isNotEmpty) {
279      print("============>" + _password);
280      widget.auth.changePassword(_password);
281    } else {
282      print("password feild empty");
283    }
284  }
285
286  void _removeUser() {
287    widget.auth.deleteUser();
288  }
289
290  void _sendResetPasswordMail() {
291    if (_resetPasswordEmail != null && _resetPasswordEmail.isNotEmpty) {
292      print("============>" + _resetPasswordEmail);
293      widget.auth.sendPasswordResetMail(_resetPasswordEmail);
294    } else {
295      print("password feild empty");
296    }
297  }
298
299  _showChangePasswordContainer() {
300    return Container(
301      decoration: BoxDecoration(
302        borderRadius: BorderRadius.circular(30.0),
303        color: Colors.brown
304      ),
305      padding: EdgeInsets.fromLTRB(10, 20, 10, 20),
306      child: Column(
307        children: <Widget>[
308          new TextFormField(
309            controller: _passwordFilter,
310            decoration: new InputDecoration(
311              contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
312              hintText: "Enter New Password",
313              border:
314                  OutlineInputBorder(borderRadius: BorderRadius.circular(22.0)),
315            ),
316          ),
317          new MaterialButton(
318            shape: RoundedRectangleBorder(
319                borderRadius: new BorderRadius.circular(30.0)),
320            onPressed: () {
321              _changePassword();
322            },
323            minWidth: MediaQuery.of(context).size.width,
324            padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
325            color: Colors.blueAccent,
326            textColor: Colors.white,
327            child: Text(
328              "Change Password",
329              textAlign: TextAlign.center,
330            ),
331          ),
332        ],
333      ),
334    );
335  }
336
337  _showSentResetPasswordEmailContainer() {
338    return Column(
339      children: <Widget>[
340        new Container(
341          child: new TextFormField(
342            controller: _resetPasswordEmailFilter,
343            decoration: new InputDecoration(
344              contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
345              hintText: "Enter Email",
346              border:
347                  OutlineInputBorder(borderRadius: BorderRadius.circular(22.0)),
348            ),
349          ),
350        ),
351        new MaterialButton(
352          shape: RoundedRectangleBorder(
353              borderRadius: new BorderRadius.circular(30.0)),
354          onPressed: () {
355            _sendResetPasswordMail();
356          },
357          minWidth: MediaQuery.of(context).size.width,
358          padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
359          color: Colors.blueAccent,
360          textColor: Colors.white,
361          child: Text(
362            "Send Password Reset Mail",
363            textAlign: TextAlign.center,
364          ),
365        ),
366      ],
367    );
368  }
369
370  _removeUserContainer() {
371    return new MaterialButton(
372      shape:
373          RoundedRectangleBorder(borderRadius: new BorderRadius.circular(30.0)),
374      onPressed: () {
375        _removeUser();
376      },
377      minWidth: MediaQuery.of(context).size.width,
378      padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
379      color: Colors.red,
380      textColor: Colors.white,
381      child: Text(
382        "Remove User",
383        textAlign: TextAlign.center,
384      ),
385    );
386  }
387}

سپس یک صفحه به نام root_page.dart ایجاد کرده و کد زیر را در آن قرار می‌دهیم:

1import 'package:flutter/material.dart';
2import './login_signup_page.dart';
3import '../services/authentication.dart';
4import './home_page.dart';
5
6class RootPage extends StatefulWidget {
7  RootPage({this.auth});
8
9  final BaseAuth auth;
10
11  @override
12  State<StatefulWidget> createState() => new _RootPageState();
13}
14
15enum AuthStatus {
16  NOT_DETERMINED,
17  NOT_LOGGED_IN,
18  LOGGED_IN,
19}
20
21class _RootPageState extends State<RootPage> {
22  AuthStatus authStatus = AuthStatus.NOT_DETERMINED;
23  String _userId = "";
24
25  @override
26  void initState() {
27    super.initState();
28    widget.auth.getCurrentUser().then((user) {
29      setState(() {
30        if (user != null) {
31          _userId = user?.uid;
32        }
33        authStatus =
34            user?.uid == null ? AuthStatus.NOT_LOGGED_IN : AuthStatus.LOGGED_IN;
35      });
36    });
37  }
38
39  void _onLoggedIn() {
40    widget.auth.getCurrentUser().then((user){
41      setState(() {
42        _userId = user.uid.toString();
43      });
44    });
45    setState(() {
46      authStatus = AuthStatus.LOGGED_IN;
47
48    });
49  }
50
51  void _onSignedOut() {
52    setState(() {
53      authStatus = AuthStatus.NOT_LOGGED_IN;
54      _userId = "";
55    });
56  }
57
58  Widget _buildWaitingScreen() {
59    return Scaffold(
60      body: Container(
61        alignment: Alignment.center,
62        child: CircularProgressIndicator(),
63      ),
64    );
65  }
66
67  @override
68  Widget build(BuildContext context) {
69    switch (authStatus) {
70      case AuthStatus.NOT_DETERMINED:
71        return _buildWaitingScreen();
72        break;
73      case AuthStatus.NOT_LOGGED_IN:
74        return new LoginSignUpPage(
75          auth: widget.auth,
76          onSignedIn: _onLoggedIn,
77        );
78        break;
79      case AuthStatus.LOGGED_IN:
80        if (_userId.length > 0 && _userId != null) {
81          return new HomePage(
82            userId: _userId,
83            auth: widget.auth,
84            onSignedOut: _onSignedOut,
85          );
86        } else return _buildWaitingScreen();
87        break;
88      default:
89        return _buildWaitingScreen();
90    }
91  }
92}

در این کد تصمیم‌گیری می‌شود که در زمان بارگذاری اپلیکیشن کدام صفحه باید بارگذاری شود. اگر کاربر ورود کرده باشد، به صفحه ورود هدایت می‌شود. در غیر این صورت اگر کاربر از قبل احراز هویت شده باشد، به صفحه اصلی هدایت خواهد شد.

در نهایت فایل main.dart را به صورت زیر تغییر می‌دهیم:

1import 'package:flutter/material.dart';
2import './pages/root_page.dart';
3import './services/authentication.dart';
4
5void main() => runApp(MyApp());
6
7
8class MyApp extends StatelessWidget {
9
10  @override
11  Widget build(BuildContext context) {
12    return MaterialApp(
13      title: 'Startup Name Generator',
14      home: new RootPage(auth: new Auth())
15      );
16  }
17  
18}

اکنون می‌توانید اپلیکیشن را با اجرای دستور flutter run روی ترمینال باز کنید.

احراز هویت فایربیس با فلاتر
احراز هویت فایربیس با فلاتر
احراز هویت فایربیس با فلاتر
احراز هویت فایربیس با فلاتر

سخن پایانی

در این راهنما با شیوه استفاده از فایربیس برای لاگین کاربران از طریق اپلیکیشن‌های موبایل و اجرای کارکردهای دیگر در فایربیس آشنا شدیم. بدین ترتیب می‌توانید یک اپلیکیشن احراز هویت با استفاده از فایربیس ایجاد کنید. اگر در هر مرحله از اجرای اپلیکیشن با مشکل مواجه شدید، می‌توانید کد کامل این پروژه را در این ریپوی گیت‌هاب (+) ملاحظه کنید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۴ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
abeythilakeudara3
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *