Is there a way to find all users nearby current user Ionic 5 + Firebase

0

i’ve been doing a lot of research these days to find a way to display a map like waze (You can navigate and you can see the users using the app near from you). For this app, i use firebase and ionic 5, i can display one user’s position (the current user), but i can’t find a way to find and display others user’s position, since it’s the core of the app it’s really important. I also need to refresh users position every 15 seconds, this will be very heavy for client side no ?

I haven’t find an API or a way to do it and this project means a lot to me so i would be pleased if someone could give me some advices for this one,

Here’s my code for displaying the map :

import { ModalAlertPage } from './../dialog/modal-alert/modal-alert.page';
import { GeoPos } from './../shared/geopos';

import { UserService } from './../user.service';
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { Plugins } from '@capacitor/core';
const { Geolocation } = Plugins;
import * as firebase from 'Firebase';
import { interval, Observable } from 'rxjs';
import { Router } from '@angular/router';
import { Device } from '@ionic-native/device/ngx';
import { ModalController, Platform } from '@ionic/angular';
declare var google: any;

/*
Source : https://www.djamware.com/post/5a48517280aca7059c142972/ionic-3-angular-5-firebase-and-google-maps-location-tracking
*/

@Component({
  selector: 'app-tab2',
  templateUrl: 'tab2.page.html',
  styleUrls: ['tab2.page.scss']
})
export class Tab2Page implements OnInit {
  @ViewChild('map') mapElement: ElementRef;
  map: any;
  markers = [];
  ref = firebase.database().ref('geolocations/');
  geoposition = {} as GeoPos;
  geoposRef;
  coords: any;
  isTracking = false;

  user = JSON.parse(localStorage.getItem('user'));
  constructor(public platform: Platform, public router: Router, private device: Device, public modalController: ModalController) {
    platform.ready().then(() => {
      this.initMap();
    });
    this.ref.on('child_changed', resp => {
      this.deleteMarkers();
      snapshotToArray(resp).forEach(data => {
        if (data.uuid !== this.device.uuid) {
          let image = 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png';
          let updatelocation = new google.maps.LatLng(data.latitude, data.longitude);
          this.addMarker(updatelocation, image);
          this.setMapOnAll(this.map);
        } else {
          let image = 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png';
          let updatelocation = new google.maps.LatLng(data.latitude, data.longitude);
          this.addMarker(updatelocation, image);
          this.setMapOnAll(this.map);
        }
      });
    });
  }

  async presentModal() {
    const modal = await this.modalController.create({
      component: ModalAlertPage,
      cssClass: 'modal-alert',
      componentProps: {
        'user': firebase.auth().currentUser
        //TODO IMPLEMENTER LA NOTIFICATION 
      },
      backdropDismiss: true,
      showBackdrop: true
    });
    return await modal.present();
  }

  ngOnInit(): void {

  }

  stopGoogleGeolocation(identifier) {
    Geolocation.clearWatch(identifier);
  }
  //TESTS COPIÉS
  initMap() {
    let watch;
    Geolocation.getCurrentPosition({ maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }).then((resp) => {
      let mylocation = new google.maps.LatLng(resp.coords.latitude, resp.coords.longitude);
      console.log(Geolocation.getCurrentPosition());

      this.map = new google.maps.Map(this.mapElement.nativeElement, {
        zoom: 15,
        center: mylocation
      });
    });
    return watch = Geolocation.watchPosition({}, (position, err) => {
      this.deleteMarkers();
      let updatelocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
      let image = 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png';
      this.addMarker(updatelocation, image);
      this.setMapOnAll(this.map);
    });
  }

  addMarker(location, image) {
    let marker = new google.maps.Marker({
      position: location,
      map: this.map,
      icon: image
    });
    this.markers.push(marker);
  }

  setMapOnAll(map) {
    for (var i = 0; i < this.markers.length; i++) {
      this.markers[i].setMap(map);
    }
  }

  clearMarkers() {
    this.setMapOnAll(null);
  }

  deleteMarkers() {
    this.clearMarkers();
    this.markers = [];
  }
}
export const snapshotToArray = snapshot => {
  let returnArr = [];

  snapshot.forEach(childSnapshot => {
    let item = childSnapshot.val();
    item.key = childSnapshot.key;
    returnArr.push(item);
  });

  return returnArr;
};

This one allows me to find only one user, should i for example, create a radius around him and retrieve users in this radius ? But how to find them ? I’m a bit lost …

Thanks a lot :slight_smile:

Hey there,

What I would do is to have a separate collection called “usersInMap” (or something like that), where from every user’s phone I’d get their coordinates and add them to the map. (This turned off by default and only on with user consent).

Then you can query that list of users to paint them on the map based on whatever you want.