Search code examples
androidgoogle-mapsandroid-intentfirebase-realtime-databaseinfowindow

Passing Firebase information through putExtra in InfoWindow OnClickListener


So I have this code that fetches the data from my Firebase Database. And then, I placed it in the variables. Markers are made using the variables. These variables are going to be used too, to pass information through putExtra in onInfoWindowClickListener.

DatabaseReference myRef = FirebaseDatabase.getInstance().getReference();
    myRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            int ikonLokasi = 0;
            for(DataSnapshot child : dataSnapshot.child("places").getChildren())
            {
                latitude_ = child.child("latitude").getValue(Double.class);
                longitude_ = child.child("longitude").getValue(Double.class);
                nama_tempat = child.child("nama").getValue(String.class);
                kategori = child.child("kategori").getValue(String.class);
                alamat = child.child("alamat").getValue(String.class);
                harga = child.child("harga").getValue(String.class);
                nomor_telepon = child.child("nomor_telepon").getValue(String.class);

                .
                .
                .

                LatLng latlng = new LatLng(latitude_, longitude_);
                googleMap.addMarker(new MarkerOptions()
                        .position(latlng)
                        .title(nama_tempat)
                        .icon(BitmapDescriptorFactory.fromResource(ikonLokasi))
                        .snippet(alamat));
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    .
    .
    .

    googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {

        @Override
        public boolean onMarkerClick(Marker marker) {
            marker.showInfoWindow();
            return true;
        }
    });

    googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
        @Override
        public void onInfoWindowClick(Marker marker) {
            marker.getTitle();
            Intent mainIntent = new Intent(getActivity(),DetailsActivity.class);
            mainIntent.putExtra("Judul", nama_tempat);
            mainIntent.putExtra("Alamat", alamat);
            mainIntent.putExtra("Harga", harga);
            mainIntent.putExtra("NomorTelepon", nomor_telepon);
            getActivity().startActivity(mainIntent);
        }
    });

Now my problem is, every InfoWindow I clicked, the information is always showing the last data I fetch from the database. For example, I clicked the A's place marker InfoWindow, but the last fetched data from the database is E's place marker. So when the DetailsActivity uses the getExtras(), it displays the E's place information, not A's. This happened in place C and D's marker too.

Here's the code for DetailsActivity:

 Intent detailsIntent = getIntent();
    placeTitle.setText(detailsIntent.getStringExtra("Judul"));
    placeAddress.setText(detailsIntent.getStringExtra("Alamat"));
    placeNumber.setText(detailsIntent.getStringExtra("Harga"));
    placePrice.setText(detailsIntent.getStringExtra("NomorTelepon"));

Any ideas on how to solve it?


Solution

  • You are using for loop for list of data received from firebase and you are updating value to string and double. So it will keep replacing last value and your final value will be the value from the last data you will fetch. To resolve this you can use HashMap

    First create a model class for marker details

    public class Detail{
    private double latitude;
    private double longitude;
    private String nama_tempat;
    private String kategori;
    private String alamat;
    private String harga;
    private String nomor_telepon;
    
    public Detail(double latitude, double longitude, String nama_tempat, String kategori, String alamat, String harga, String nomor_telepon) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.nama_tempat = nama_tempat;
        this.kategori = kategori;
        this.alamat = alamat;
        this.harga = harga;
        this.nomor_telepon = nomor_telepon;
    }
    
    public double getLatitude() {
        return latitude;
    }
    
    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }
    
    public double getLongitude() {
        return longitude;
    }
    
    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }
    
    public String getNama_tempat() {
        return nama_tempat;
    }
    
    public void setNama_tempat(String nama_tempat) {
        this.nama_tempat = nama_tempat;
    }
    
    public String getKategori() {
        return kategori;
    }
    
    public void setKategori(String kategori) {
        this.kategori = kategori;
    }
    
    public String getAlamat() {
        return alamat;
    }
    
    public void setAlamat(String alamat) {
        this.alamat = alamat;
    }
    
    public String getHarga() {
        return harga;
    }
    
    public void setHarga(String harga) {
        this.harga = harga;
    }
    
    public String getNomor_telepon() {
        return nomor_telepon;
    }
    
    public void setNomor_telepon(String nomor_telepon) {
        this.nomor_telepon = nomor_telepon;
    }
    

    }

    And on you onDataChange use HashMap to stores the Detail object with the Marker as key. That way, Marker will be linked with the object.

        private HashMap<Marker, Detail> detailMarkerMap;
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            int ikonLokasi = 0;
            for(DataSnapshot child : dataSnapshot.child("places").getChildren())
            {
                latitude_ = child.child("latitude").getValue(Double.class);
                longitude_ = child.child("longitude").getValue(Double.class);
                nama_tempat = child.child("nama").getValue(String.class);
                kategori = child.child("kategori").getValue(String.class);
                alamat = child.child("alamat").getValue(String.class);
                harga = child.child("harga").getValue(String.class);
                nomor_telepon = child.child("nomor_telepon").getValue(String.class);
    
                Detail detail = new Detail(latitude_, longitude_, nama_tempat,   kategori, alamat, harga, nomor_telepon );
    
    
    
                .
                .
                .
    
                LatLng latlng = new LatLng(latitude_, longitude_);
                Marker marker = googleMap.addMarker(new MarkerOptions()
                .position(latlng)
                .title(nama_tempat)
                .icon(BitmapDescriptorFactory.fromResource(ikonLokasi))
                .snippet(alamat));
    
                detailMarkerMap.put(marker, detail);
            }
        }
    

    On you OnInfoWindowClick get the detail by key marker

    @Override
        public void onInfoWindowClick(Marker marker) {
            marker.getTitle();
    
            Detail detail = detailMarkerMap.get(marker);
    
            Intent mainIntent = new Intent(getActivity(),DetailsActivity.class);
            mainIntent.putExtra("Judul", detail.getNama_tempat());
            mainIntent.putExtra("Alamat", detail.getAlamat());
            mainIntent.putExtra("Harga", detail.getHarga());
            mainIntent.putExtra("NomorTelepon", detail.getNomor_telepon());
            getActivity().startActivity(mainIntent);
        }