首页 > 解决方案 > 用户登录移动应用程序后如何保存用户的位置

问题描述

我想让用户在登录移动应用程序后能够获取并将他们的位置(纬度和经度)保存到 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!

标签: firebasefluttergoogle-cloud-firestorefirebase-authentication

解决方案


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

希望这对您有用,我认为获取用户位置没有问题。


推荐阅读