用户登录移动应用程序后如何保存用户的位置
Posted
技术标签:
【中文标题】用户登录移动应用程序后如何保存用户的位置【英文标题】:How to save user's location after the user has logged into the mobile application 【发布时间】:2021-12-23 03:11:32 【问题描述】:我想让用户在登录移动应用程序后能够获取并保存他们的位置(纬度和经度)到 Firebase。他们将通过点击Profile Screen 中的“确认地址”按钮获取他们的位置。我想知道我应该如何在 Firebase 中各自的 uid 下保存他们的位置?
我已在此处附加了我的Firestore Database 屏幕作为附加信息(不确定是否有用)。
这是我的Profile Screen 的代码。我只能在移动应用程序中获取位置,但无法将位置保存到Firestore Database。由于多次失败,我也没有编写将位置保存到 Firebase 的代码。
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:quaratrack_01/models/user_model.dart';
import 'package:geolocator/geolocator.dart';
const kDefaultPadding = 20.0;
class ProfileScreen extends StatefulWidget
const ProfileScreen(Key? key) : super(key: key);
@override
_ProfileScreen createState() => _ProfileScreen();
class _ProfileScreen extends State<ProfileScreen>
User? user = FirebaseAuth.instance.currentUser;
UserModel loggedInUser = UserModel();
var locationMessage = '';
late String latitude;
late String longitude;
@override
void initState()
super.initState();
FirebaseFirestore.instance
.collection("users")
.doc(user!.uid)
.get()
.then((value)
this.loggedInUser = UserModel.fromMap(value.data());
setState(() );
);
@override
Widget build(BuildContext context)
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(appBar: AppBar(
backgroundColor: Colors.cyan[50],
leading: IconButton(
icon: Icon(Icons.menu),
iconSize: 35,
color: Colors.black,
onPressed: () ,
),
title: const Text("Profile"),
titleTextStyle: TextStyle(color: Colors.black, fontSize: 30, fontWeight: FontWeight.bold),
centerTitle: true),
body: SafeArea(
child: SingleChildScrollView(
padding: EdgeInsets.only(
top: kDefaultPadding / 2,
left: kDefaultPadding / 3,
right: kDefaultPadding / 3,
bottom: kDefaultPadding / 3,
),
child: Column(
children: [
Form(
child: Column(
children: [
buildNameField(),
SizedBox(
height: kDefaultPadding,
),
buildICField(),
SizedBox(height: kDefaultPadding,
),
buildPhoneField(),
SizedBox(
height: kDefaultPadding,
),
buildEmailField(),
SizedBox(height: kDefaultPadding,
),
buildLocationField(),
SizedBox(height: kDefaultPadding * 1.5,
),
Material(
elevation: 5,
borderRadius: BorderRadius.circular(40),
color: Colors.blueAccent,
child:MaterialButton(
padding: EdgeInsets.fromLTRB(20, 17, 20, 17),
minWidth: 100,
onPressed: () getCurrentLocation();,
child: Text(
"CONFIRM ADDRESS",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25, color: Colors.white, fontWeight: FontWeight.bold),
),
),
)
])
)],
)),
),
),
);
TextFormField buildNameField()
return TextFormField(
keyboardAppearance: Brightness.light,
keyboardType: TextInputType.name,
decoration: InputDecoration(
labelText: 'Name:',
labelStyle: TextStyle(color: Colors.black, fontSize: 28, fontWeight: FontWeight.bold),
hintText: "$loggedInUser.firstName $loggedInUser.secondName",
hintStyle: TextStyle(color: Colors.black, fontSize: 20),
enabled: false,
floatingLabelBehavior: FloatingLabelBehavior.always,
icon: Icon(Icons.account_circle, color: Colors.blue, size: 35),
),
);
TextFormField buildICField()
return TextFormField(
keyboardAppearance: Brightness.light,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'IC/Passport No:',
labelStyle: TextStyle(color: Colors.black, fontSize: 28, fontWeight: FontWeight.bold),
hintText: '12345678',
hintStyle: TextStyle(color: Colors.black, fontSize: 20),
enabled: false,
floatingLabelBehavior: FloatingLabelBehavior.always,
icon: Icon(Icons.perm_identity, color: Colors.blue, size: 35),
),
);
TextFormField buildPhoneField()
return TextFormField(
keyboardAppearance: Brightness.light,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Phone Number:',
labelStyle: TextStyle(color: Colors.black, fontSize: 28, fontWeight: FontWeight.bold),
hintText: '0123456789',
hintStyle: TextStyle(color: Colors.black, fontSize: 20),
enabled: false,
floatingLabelBehavior: FloatingLabelBehavior.always,
icon: Icon(Icons.call_rounded, color: Colors.blue, size: 35),
),
);
TextFormField buildEmailField()
return TextFormField(
keyboardAppearance: Brightness.light,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email Address:',
labelStyle: TextStyle(color: Colors.black, fontSize: 28, fontWeight: FontWeight.bold),
hintText: "$loggedInUser.email",
hintStyle: TextStyle(color: Colors.black, fontSize: 20),
enabled: false,
floatingLabelBehavior: FloatingLabelBehavior.always,
icon: Icon(Icons.mail, color: Colors.blue, size: 35),
),
);
TextFormField buildLocationField()
return TextFormField(
keyboardAppearance: Brightness.light,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Quarantine Location:',
labelStyle: TextStyle(color: Colors.black, fontSize: 28, fontWeight: FontWeight.bold),
hintText: locationMessage,
hintStyle: TextStyle(color: Colors.red, fontSize: 20),
enabled: false,
floatingLabelBehavior: FloatingLabelBehavior.always,
icon: Icon(Icons.location_city, color: Colors.blue, size: 35),
),
);
void getCurrentLocation() async
var position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
var lat = position.latitude;
var long = position.longitude;
//passing this to latitude and longitude strings
latitude = "$lat";
longitude = "$long";
setState(()
locationMessage = "Lat: $lat, Long: $long";
);
//Appreciate if someone can help! Please!
【问题讨论】:
【参考方案1】:Firestore 有一个名为 geopoint
的字段类型,其中包含纬度和经度字段。因此,您所要做的就是设置一个 Geopoint 类型的新字段,如下所示:
import 'package:cloud_firestore/cloud_firestore.dart';
//update an exist user or or save it, as you like:
await FirebaseFirestore.instance
.collection("users")
.doc(user!.uid).update(location:
GeoPoint(latitude as double, longitude as double)
);
希望这对你有用,我假设获取用户位置没有问题。
【讨论】:
以上是关于用户登录移动应用程序后如何保存用户的位置的主要内容,如果未能解决你的问题,请参考以下文章