Display nearby users in Google Maps with Ionic + Geofire
- Fire Focus
- Oct 7, 2020
- 2 min read
Introduction
In this video,I will show you how you can display nearby users in google maps with Ionic , Firebase.Here, we are using GeoFire and Angular Google Maps.
What is GeoFire?
GeoFire is an open-source JavaScript library that allows you to store and query a set of items based on their geographic location. GeoFire uses Firebase for data storage, allowing query results to be updated in realtime as they change. GeoFire does more than just measure the distance between locations; it selectively loads only the data near certain locations, keeping your applications light and responsive, even with extremely large datasets.
Install Packages
Install Firebase,GeoFire and Angular Google Maps using below commands:
npm i firebase --save
npm i geofire --save
npm install @agm/core --save
Initialize AGM
Then in you app level module or page level module typescript file, initialize Angular Google Maps.
import { AgmCoreModule } from '@agm/core';
imports: [
AgmCoreModule.forRoot({
apiKey:"your_api_key"
})
]
Get and Set location
Get current user location using native location service and set that location in database using GeoFire.
After getting and storing user's location, we load users around using GeoFire and store it in an array.
Here, we have a mathod to covert distance.
map.page.ts
import { Component, OnInit } from '@angular/core';
import * as firebase from "firebase";
@Component({
selector: 'app-map',
templateUrl: './map.page.html',
styleUrls: ['./map.page.scss'],
})
export class MapPage implements OnInit {
lat: number;
lng: number;
uid = firebase.auth().currentUser.uid;
geoFire: any;
isLoaded: boolean = false;
usersAround: Array<any> = [];
constructor() {
const geofire = require('geofire');
var dbRef = firebase.database().ref("locations");
this.geoFire = new geofire.GeoFire(dbRef);
}
getUserLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
this.geoFire.set(this.uid, [this.lat, this.lng]).then(() => {
this.getUsersAround();
});
});
}
}
getUsersAround() {
this.geoFire.query({
center: [this.lat, this.lng],
radius: 1.609 //kilometers
}).on("key_entered", (key, location, distance) => {
firebase.database().ref("users/" + key).once("value", snap => {
this.usersAround.push({ ...snap.val(), location: location, distance: distance });
this.isLoaded = true;
});
});
}
convert(distance) {
//distance is something like 1.694843322102
//we convert it to 1.6 km
//if distance is less than one
//return value in meters
if (distance <= 1) {
return Number(distance * 1000).toFixed(2) + " m away";
}
//else return value in kilometers
else {
return Number(distance).toFixed(2) + " km away";
}
}
}
Setting up the UI
We use Angular Google Maps to dispaly our location and users around ourself.
map.page.html
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title>Users Around</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<!-- Show Loader before loading -->
<div class="center" *ngIf="!isLoaded">
<ion-spinner color="primary"></ion-spinner>
</div>
<!-- Google Maps -->
<agm-map [zoom]="18" [latitude]="lat" [longitude]="lng">
<!-- Your Location Marker -->
<agm-marker [latitude]="lat" [longitude]="lng">
<!-- Popover on click -->
<agm-info-window>
<p>
You are here
</p>
</agm-info-window>
</agm-marker>
<!-- Nearby Users -->
<ng-container *ngFor="let user of usersAround">
<agm-marker *ngIf="user.uid != uid" [latitude]="user.location[0]" [longitude]="user.location[1]" [iconUrl]="{url: user.dp,
scaledSize: {
width: 30,
height: 30}
}">
<!-- Popover on click -->
<agm-info-window>
<ion-item lines="none">
<ion-avatar slot="start">
<img src="{{user.dp}}" />
</ion-avatar>
<ion-label>
<h2>{{user.name}}</h2>
<p>{{convert(user.distance)}}</p>
</ion-label>
</ion-item>
<ion-button expand="block" fill="clear">
See Profile
</ion-button>
</agm-info-window>
</agm-marker>
</ng-container>
</agm-map>
</ion-content>
map.page.scss
agm-map{
//necessary to set width and height
//if not set map is not shown
width: 100vw;
height: 100vh;
}
I hope you understand the lesson.Please leave your feedback in comments.Cheers!
Commenti