firebase - 用户登录移动应用程序后如何保存用户的位置
问题描述
我想让用户在登录移动应用程序后能够获取并将他们的位置(纬度和经度)保存到 firebase。他们将通过单击“个人资料屏幕”中的“确认地址”按钮来获取他们的位置。我想知道我应该如何在 Firebase 中各自的 uid 下保存他们的位置?
我在此处附加了我的Firestore 数据库屏幕作为附加信息(不确定它是否有用)。
这是我的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!
解决方案
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)
});
希望这对您有用,我认为获取用户位置没有问题。
推荐阅读
- docker - 我可以在容器初始化时创建解析器类吗?
- c - 为什么在这里使用 strdup()?
- ios - “捆绑
操作尝试在具有 CurrentValueSubject 绑定的 TextField 上每帧更新多次 - python-3.x - 使用 gitpython 推送到 GitLab 后如何获取信息
- c - 是否可以在内核模块的根路径中创建目录?
- xcode - 导航栏被隐藏但不允许在 SwiftUI 中单击标题按钮
- flutter - 如何添加如下图所示的启动画面?
- python - 如何比较数据类?
- javascript - 代码在预期之前执行,async/await 没有按预期工作
- python - “/”处的 NoReverseMatch