用户登录移动应用程序后如何保存用户的位置

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)
     );

希望这对你有用,我假设获取用户位置没有问题。

【讨论】:

以上是关于用户登录移动应用程序后如何保存用户的位置的主要内容,如果未能解决你的问题,请参考以下文章

Android登录后的用户数据如何保存,Android如何保存数据

用户登录后如何在React中保存用户信息

laravel - 在登录移动应用程序时保存会话凭据

如何设置用户登录后的欢迎信息?

如何利用cookie来保存用户登录账号

java如何用cookies保存用户登录信息