在颤动中将登录的用户存储到云 Firestore
Posted
技术标签:
【中文标题】在颤动中将登录的用户存储到云 Firestore【英文标题】:Store logged in users to cloud Firestore in flutter 【发布时间】:2021-02-04 04:17:09 【问题描述】:在我的 Flutter 应用中,用户使用手机登录。那么如何将用户 ID 存储在云 Firestore 中并保存帐户以供用户再次登录并保留其详细信息? (我使用共享偏好来检查用户是否已登录)
如果需要,这是我的代码。
import 'package:country_code_picker/country_code_picker.dart';
import 'package:demo/Firebase/auth.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'BottomBarPages/home.dart';
class SignIn extends StatefulWidget
@override
_SignInState createState() => _SignInState();
class _SignInState extends State<SignIn>
TextEditingController phoneController = new TextEditingController();
String phoneNumber = "";
SharedPreferences logindata;
bool newuser;
bool shower = false;
String smsCode;
String verificationCode;
@override
void initState()
// TODO: implement initState
super.initState();
check_if_already_login();
void check_if_already_login() async
logindata = await SharedPreferences.getInstance();
newuser = (logindata.getBool('login') ?? true);
print(newuser);
if (newuser == false)
Navigator.pushReplacement(
context, new MaterialPageRoute(builder: (context) => Home()));
@override
void dispose()
// Clean up the controller when the widget is disposed.
phoneController.dispose();
super.dispose();
void _onCountryChange(CountryCode countryCode)
this.phoneNumber = countryCode.toString();
print("New Country selected: " + countryCode.toString());
void check()
final myPhone = this.phoneNumber + phoneController.text;
print("Full Text: " + myPhone);
Future<void> man() async
Future<void> submit() async
final myPhone = this.phoneNumber + phoneController.text;
final PhoneVerificationCompleted verificationCompleted =
(AuthCredential credential)
;
final PhoneVerificationFailed verificationFailed =
(AuthException exception) ;
final PhoneCodeSent phoneCodeSent = (String verId, [int forceCodeResend])
this.verificationCode = verId;
smsCodeDialog(context).then((value) => print("signed"));
;
final PhoneCodeAutoRetrievalTimeout autoRetrievalTimeout = (String verId)
this.verificationCode = verId;
;
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: myPhone,
timeout: const Duration(seconds: 5),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: phoneCodeSent,
codeAutoRetrievalTimeout: autoRetrievalTimeout);
Future<bool> smsCodeDialog(BuildContext context)
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context)
return AlertDialog(
title: Text(
'Enter Code',
style: TextStyle(color: Colors.lightGreen, fontSize: 24),
),
content: TextField(
keyboardType: TextInputType.number,
onChanged: (Value)
smsCode = Value;
,
),
contentPadding: EdgeInsets.all(10),
actions: [
FlatButton(
onPressed: ()
String phone = phoneController.text;
if (phone != '')
print('Successfull');
logindata.setBool('login', false);
logindata.setString('username', phone);
Navigator.push(context,
MaterialPageRoute(builder: (context) => Home()));
else
Navigator.of(context).pop();
signIn();
// FirebaseAuth.instance.currentUser().then((user)
// if (user != null)
// Navigator.of(context).pop();
// Navigator.push(context,
// MaterialPageRoute(builder: (context) => Home()));
// else
// Navigator.of(context).pop();
// signIn();
//
// );
,
child: Text(
'Verify',
style: TextStyle(fontSize: 20, color: Colors.lightGreen),
))
],
);
);
// CircularProgressIndicator(
// valueColor: new AlwaysStoppedAnimation<Color>(Colors.lightGreen),
// value: 0.25,
// );
signIn()
AuthCredential phoneAuthCredential = PhoneAuthProvider.getCredential(
verificationId: verificationCode, smsCode: smsCode);
FirebaseAuth.instance
.signInWithCredential(phoneAuthCredential)
.then((user) => Navigator.push(
context, MaterialPageRoute(builder: (context) => Home())))
.catchError((e) => print(e));
@override
Widget build(BuildContext context)
return GestureDetector(
onTap: ()
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus)
currentFocus.unfocus();
,
child: Scaffold(
body: Column(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: [0.1, 0.3, 1.0],
colors: [
Colors.lightGreen[300],
Colors.white,
Colors.lightGreen[50]
],
),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 150,
child: Image.asset('images/phone.png'),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(color: Colors.lightGreen)),
width: double.infinity,
height: 40,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CountryCodePicker(
dialogTextStyle: TextStyle(fontSize: 20),
onChanged: _onCountryChange,
initialSelection: 'US',
favorite: ['+251', 'ET'],
),
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: SizedBox(
width: 150,
child: TextFormField(
controller: phoneController,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
border: InputBorder.none,
),
),
),
),
],
),
),
),
),
SizedBox(
height: 20,
),
MaterialButton(
onPressed: submit,
minWidth: MediaQuery.of(context).size.width - 80,
height: 45,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Colors.lightGreen,
splashColor: Colors.green,
child: Text(
"Confirm",
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 14, horizontal: 64),
child: Text(
"you'll receive a 6 digit code click Confirm to verify",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Colors.lightGreen,
),
),
),
],
),
),
),
),
],
),
),
);
帮助我了解如何存储用户信息。
【问题讨论】:
【参考方案1】:我从来没有使用过手机号登录,但我通常是这样的:
首先我让用户登录,然后我得到他们的 uid。它应该与您登录后获得的用户对象一起提供。
在 Firestore 中,我之前创建了一个集合“UserData”。
当我得到用户的 uid 时,我检查“UserData”中是否已经有一个文档。
如果没有,那么我继续创建文档并保存用户信息。
如果文档已经存在,我会阅读用户信息。
编辑:
以下是有关 SignIn 方法的所有文档:Here
用户登录后,您必须使用 Firestore,以便存储您以某种方式收集的用户信息。
这里是 Firestore 文档:Here
现在您需要了解用户是否是第一次登录。这取决于您。 当您获得此信息时:
如果是用户第一次登录,我会直接将信息添加到数据库中。这是一个示例(不要直接复制和粘贴此代码,因为正如我所说,流程很大程度上取决于您的应用代码)。
CollectionReference users = FirebaseFirestore.instance.collection('users');
users.add(
'full_name': fullName, // John Doe
'company': company, // Stokes and Sons
'age': age // 42
)
.then((value) => print("User Added"))
.catchError((error) => print("Failed to add user: $error"));
现在,每次“老”用户登录时,我都会使用 get 检索数据:
CollectionReference users = FirebaseFirestore.instance.collection('users');
users.doc(documentId).get()
【讨论】:
这可能是很多代码,并且很大程度上取决于您的应用程序。我将添加一些您可以使用的文档的详细信息和链接。以上是关于在颤动中将登录的用户存储到云 Firestore的主要内容,如果未能解决你的问题,请参考以下文章