This is the second part of the location tracking tutorial. I hope you guy’s have seen my previous article in which we’ve developed the Driver App.

In this tutorial, we’re going to develop the Passenger App. Here, we are not going to do the same work which we’ve done in the previous article like creating a Google Map API key or creating a Firebase project.

So, without wasting a time let’s dive into Android Studio and start making the Passenger App.

Passenger App

First, add the below dependencies to your app level build.gradle file.

implementation ''
implementation ''
implementation ''

After adding the dependencies you need to sync or build your project. Later the successful build adds the Internet and Location permission to Android. Manifest file.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

There’s one more thing we need to do, to show the Google Maps in the Android App. Add the below meta tags in Android. Manifest file.

<meta-data android:name="" 
           android:value="@integer/google_play_services_version" />
 <meta-data android:name="" 
            android:value="@string/map_api_key" />  // change it your Google Maps Api key or directly paste API key here.

Now in this app, we don’t need to create a new Firebase project. Below are the steps you need to do for add firebase in Passenger App.

  1. Sign In Firebase Console and open the previous project which you create when working with Driver App.
  2. Click on Settings Icon -> Project Settings.
  3. In General, tab click on Add app -> Add Firebase to your Android app.
  4. After adding the Android app to firebase project download the latest google-services.json file and add to the app directory of your Android app.

All the prep work being done regarding firebase and Google Maps. Now let’s start making Passenger app. Below is the UI of Passenger App that we’re gonna make.

Passenger App UI

You see the UI is very basic, we’ve got a Google Maps and a TextView which tells how many drivers are currently online. The following shows the code of the above UI.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""

        tools:context="" />

        android:textSize="15sp" />



class MainActivity : AppCompatActivity(), FirebaseDriverListener {

    companion object {
        private const val MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 6161
        private const val ONLINE_DRIVERS = "online_drivers"

    private lateinit var googleMap: GoogleMap
    private lateinit var locationProviderClient: FusedLocationProviderClient
    private lateinit var locationRequest: LocationRequest
    private lateinit var locationCallback: LocationCallback
    private var locationFlag = true
    private lateinit var valueEventListener: FirebaseEventListenerHelper
    private val uiHelper = UiHelper()
    private val googleMapHelper = GoogleMapHelper()
    private val databaseReference = FirebaseDatabase.getInstance().reference.child(ONLINE_DRIVERS)

    override fun onCreate(savedInstanceState: Bundle?) {
        val mapFragment: SupportMapFragment = supportFragmentManager.findFragmentById( as SupportMapFragment
        mapFragment.getMapAsync { googleMap = it }
        locationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        locationRequest = uiHelper.getLocationRequest()
        if (!uiHelper.isPlayServicesAvailable(this)) {
            Toast.makeText(this, "Play Services did not installed!", Toast.LENGTH_SHORT).show()
        } else requestLocationUpdate()
        valueEventListener = FirebaseEventListenerHelper(this)

    private fun requestLocationUpdate() {
        if (!uiHelper.isHaveLocationPermission(this)) {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION)
        if (uiHelper.isLocationProviderEnabled(this))
            uiHelper.showPositiveDialogWithListener(this, resources.getString(R.string.need_location), resources.getString(R.string.location_content), object : IPositiveNegativeListener {
                override fun onPositive() {
            }, "Turn On", false)
        locationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())

    private fun createLocationCallback() {
        locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult?) {
                if (locationResult!!.lastLocation == null) return
                val latLng = LatLng(locationResult.lastLocation.latitude, locationResult.lastLocation.longitude)
                Log.e("Location", latLng.latitude.toString() + " , " + latLng.longitude)
                if (locationFlag) {
                    locationFlag = false

    private fun animateCamera(latLng: LatLng) {
        val cameraUpdate = googleMapHelper.buildCameraUpdate(latLng)
        googleMap.animateCamera(cameraUpdate, 10, null)

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            val value = grantResults[0]
            if (value == PackageManager.PERMISSION_DENIED) {
                Toast.makeText(this, "Location Permission denied", Toast.LENGTH_SHORT).show()
            } else if (value == PackageManager.PERMISSION_GRANTED) requestLocationUpdate()

    override fun onDriverAdded(driver: Driver) {
        val markerOptions = googleMapHelper.getDriverMarkerOptions(LatLng(, driver.lng))
        val marker = googleMap.addMarker(markerOptions)
        marker.tag = driver.driverId
        totalOnlineDrivers.text = resources.getString(R.string.total_online_drivers).plus(" ").plus(MarkerCollection.allMarkers().size)

    override fun onDriverRemoved(driver: Driver) {
        totalOnlineDrivers.text = resources.getString(R.string.total_online_drivers).plus(" ").plus(MarkerCollection.allMarkers().size)

    override fun onDriverUpdated(driver: Driver) {
        val marker = MarkerCollection.getMarker(driverId = driver.driverId)
        MarkerAnimationHelper.animateMarkerToGB(marker!!, LatLng(, driver.lng), LatLngInterpolator.Spherical())

    override fun onDestroy() {

The MainActivity got a bunch of important points which I’m going to explain below.

  • databaseReference: The DatabaseReference will be the online-drivers node because the passenger wants to track all drivers. Now if there is more than one driver then the passenger will be able to see all drivers on Google Map. If you want to listen to the specific driver then another child node will be added with the driverId.
  • onDriverAdded: This method will be called whenever new driver online in the firebase real-time database. When the new driver comes online we show the Marker to Google Maps and store the Marker in our MarkerCollection.
  • onDriverRemoved: This function will be called when the driver goes offline in the firebase real-time database. Later that we’ll remove the driver Marker from Google Maps and from MarkerCollection as well.
  • onDriverUpdated: This method will be called when the driver current position changed. Later that we get the driver Marker from MarkerCollection and animate the Marker to driver new position.
  • onDestroy: In this method, we’re removing firebase events, removing the current location updates and clearing the MarkerCollection.

Other methods of MainActivity are same as Driver App which I’ve explained in my previous article.


object MarkerCollection {

    private val markers: MutableList<Marker> = LinkedList()

    fun insertMarker(marker: Marker) = apply {

    fun getMarker(driverId: String): Marker? {
        for (marker in markers)
            if (marker.tag == driverId) return marker
        return null

    fun clearMarkers() = apply {

    fun removeMarker(driverId: String) {
        val marker = getMarker(driverId)
        if (marker != null) markers.remove(marker)

    fun allMarkers() = markers

The following explains about MarkerCollection class.

  • insertMarker: Add the Marker instance to markers collection.
  • getMarker: When creating a Marker in MainActivity we set the driverId as a tag so, we search the Marker on the basis of Tag.
  • removeMarker: This method remove the specific driver Marker from the Google Maps when he goes offline.
  • clearMarker: Empty the Marker Collection.


class FirebaseEventListenerHelper(private val firebaseDriverListener: FirebaseDriverListener) : ChildEventListener {

    override fun onCancelled(p0: DatabaseError) {


    override fun onChildMoved(p0: DataSnapshot, p1: String?) {


    override fun onChildChanged(p0: DataSnapshot, p1: String?) {
        val driver = p0.getValue(

    override fun onChildAdded(p0: DataSnapshot, p1: String?) {
        val driver = p0.getValue(

    override fun onChildRemoved(p0: DataSnapshot) {
        val driver = p0.getValue(

This is a helper class for listening to the events in firebase real-time database. The FirebaseEventListenerHelper class implements ChildEventListener interface.


interface FirebaseDriverListener {

    fun onDriverAdded(driver: Driver)

    fun onDriverRemoved(driver: Driver)

    fun onDriverUpdated(driver: Driver)

The GoogleMapHelper, UiHelper, MarkerAnimationHelper, Driver, IPositiveNegativeListener and LatLngInterpolator classes I’ve discussed these classes in my previous article.

Alright, guys, this is here we complete both of our apps. If you’ve any queries regarding this post please do comment below.

Download Complete Code

Thank you for being here and keep reading…

Here’re some more related articles:

Everything You Need To Know About Using Google Maps In Cab Booking App

5 Best Android Tracking Apps to Find It All

Building A Location Distance Tracking App | Android

Previous Part


I’m a mobile product devsigner (i.e. I consider myself as both a developer and a designer) and user experience/interface engineer. I’m an expert on the Android platform and have been recognized as it by the community.


  1. How to upload direction to firebase using compass so that I can see the direction of car

  2. shahzaib

    You need to add firebase child listener for showing multiple drivers

    • can u please show the screenshot or explain in detail

  3. Why google map not showing. I already put my api showing online driver 1 but not showing into google map

    • Hey Asif,
      Did you enable billing to your account becuase Google new privacy policy says you have attach credit card details in order to use the services.

  4. shahzaib

    how to add multiple online drivers on firebase

    • Hey Shahzaib,
      You just need to run the application in two devices with unique driverId and simply online the driver.

  5. Great Project…….., But when i installed “driver app” in two android device then “passenger app ” showing only one driver is online. And firebase database also showing one device lat lng.

    • Hey Pradip,
      In order to show multiple drivers online, you need to change the driverKey inside Driver model class and run the application.