Я использую Google Maps Android SDK, чтобы заполнить карту маркерами, чьи местоположения хранятся в базе данных Firebase, общей для всех пользователей моего приложения. Данные для каждого маркера хранятся в уникальной записи Firebase, и каждая запись содержит широту и долготу маркера вместе с логическим значением, указывающим, было ли местоположение проверено.
Маркеры первоначально добавляются на карту через прослушиватель childAdded. Затем приложение «прослушивает» базу данных Firebase для следующих событий:
- Добавлен новый маркер
- Существующий маркер изменен (перемещен в новое место и / или " проверено ")
- Существующий маркер удален
Я реализовал карту ha sh, как показано в Как обновить позиции маркера с помощью данных из Firebase Google Maps API Android.
Когда добавляется маркер, записи добавляются на карту ha sh, где pushID (ключ) Firebase используется в качестве индекса для объекта маркера в ha sh map (см. код ниже).
private Map<String, Marker> mMarkerMap = new HashMap<> ();
DatabaseReference dbRef = FirebaseDatabase.getInstance ().getReference ();
DatabaseReference markerRef = dbRef.child ( "markers" );
//load all markers when app starts
//child added returns all markers, then listens for new additions
//Log.i(TAG, "Database Reference: " + dbRef);
//List<SymbolOptions> options = new ArrayList<> ();
markerRef.addChildEventListener ( new ChildEventListener () {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
try {
markerKey = dataSnapshot.getKey ();
Log.i ( TAG, "Adding Markers: " );
Log.i ( TAG, "Marker Key: " + markerKey );
double x = (Double) dataSnapshot.child ( "x" ).getValue ();
double y = (Double) dataSnapshot.child ( "y" ).getValue ();
boolean v = (Boolean) dataSnapshot.child ( "v" ).getValue ();
Log.i ( TAG, "Marker Data - x: " + x + " y: " + y + " v: " + v );
if (v == true) {
Marker marker = mMap.addMarker ( new MarkerOptions ()
.position ( new LatLng ( y, x ) )
.icon ( BitmapDescriptorFactory.fromResource ( R.drawable.verified ) ) );
marker.setTag(markerKey);
mMarkerMap.put (markerKey, marker);
} else {
Marker marker = mMap.addMarker ( new MarkerOptions ()
.position ( new LatLng ( y, x ) )
.icon ( BitmapDescriptorFactory.fromResource ( R.drawable.unverified ) ) );
marker.setTag(markerKey);
mMarkerMap.put (markerKey, marker);
}
} catch (Error error) {
noFirebaseAccessAlert ();
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
try {
markerKey = dataSnapshot.getKey ();
Log.i ( TAG, "Changing Marker: " );
Log.i ( TAG, "Marker Key: " + markerKey );
double x = (Double) dataSnapshot.child ( "x" ).getValue ();
double y = (Double) dataSnapshot.child ( "y" ).getValue ();
boolean v = (Boolean) dataSnapshot.child ( "v" ).getValue ();
Log.i ( TAG, "Marker Data - x: " + x + " y: " + y + " v: " + v );
Marker changedMarker = mMarkerMap.get(markerKey);
if (v == true) {
changedMarker.setPosition (new LatLng(y,x));
changedMarker.setIcon ( BitmapDescriptorFactory.fromResource ( R.drawable.verified ) );
} else {
changedMarker.setPosition (new LatLng(y,x));
changedMarker.setIcon ( BitmapDescriptorFactory.fromResource ( R.drawable.unverified ) );
}
} catch (Error error) {
noFirebaseAccessAlert ();
}
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
try {
markerKey = dataSnapshot.getKey ();
Log.i ( TAG, "Deleting Marker: " );
Log.i ( TAG, "Marker Key: " + markerKey );
Marker deletedMarker = mMarkerMap.get (markerKey);
deletedMarker.remove ();
mMarkerMap.remove(markerKey);
} catch (Error error) {
noFirebaseAccessAlert ();
}
}
Проблема заключается в том, что когда данные изменяются в Firebase и вызывается прослушиватель childChanged, на карте появляется новая иконка обновленное местоположение, но оригинальный значок остается. В таблицу ha sh не вносится никакой новой записи.
Если я нажму на любой значок, функция «onClickMarker» получит тот же идентификатор маркера. Я мог бы просто удалить существующий маркер и добавить новый, но лучше переместить существующий маркер, если это возможно.
Это известная проблема?