как отображать и удалять не свои маркера?
мне с базы firebase приходят маркера от разных пользователей, и через заданное количество времени они должны удалиться....но по факту получается, что из базы данных маркера(текущего пользователя) появляются и удаляются исправно, а с карты не удаляются у других пользователей (после перезапуска приложения они пропадают естественно)....
проверяю просто! беру 2 телефона и на одном ставлю маркер, он появляется на 2-ух телефонах, а удаляется только на том на котором установлен маркер, а на других нет(после перезапуска приложения на другом телефоне маркер пропадает естественно)
как это исправить, что бы он удалялся на всех устройствах одновременно?
делаю так:
// код для показа маркеров для других пользователей
handler = new Handler();
Runnable r = new Runnable() {
public void run() {
DatabaseReference rootRef2 = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef2 = rootRef2.child("Markers").child("Markers");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
for (DataSnapshot ds : dataSnapshot1.getChildren()) {
String key = ds.getKey();
Double latitude = ds.child("latitude").getValue(Double.class);
Double longitude = ds.child("longitude").getValue(Double.class);
LatLng location = new LatLng(latitude, longitude);
Marker marker = hashMap.get(key);
if (marker == null) {
try {
marker = mMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.img_4662878black)).draggable(false));
}} catch (Exception e) {}
hashMap.put(key, marker);
} else {
marker.setPosition(location);
}
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
uidRef2.addListenerForSingleValueEvent(valueEventListener);
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
// код для показа/удаления маркеров у текущего пользователя
DatabaseReference rootRef1 = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef1 = rootRef1.child("Markers").child("Markers").child(firebaseAuth.getCurrentUser().getUid());
uidRef1.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
String key = dataSnapshot.getKey();
Log.d(TAG, "Adding location for '" + key + "'");
Double latitude = dataSnapshot.child("latitude").getValue(Double.class);
Double longitude = dataSnapshot.child("longitude").getValue(Double.class);
LatLng location = new LatLng(latitude, longitude);
Marker marker = hashMap.get(key);
if (marker == null) {
try {
marker = mMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.img_4662878black)).draggable(false));
}
} catch (Exception e) {
}
hashMap.put(key, marker);
} else {
marker.setPosition(location);
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, @Nullable String s) {
String key1 = dataSnapshot.getKey();
Log.d(TAG, "Location for '" + key1 + "' was updated.");
Double latitude = dataSnapshot.child("latitude").getValue(Double.class);
Double longitude = dataSnapshot.child("longitude").getValue(Double.class);
LatLng location = new LatLng(latitude, longitude);
Marker marker34 = hashMap.get(key1);
if (marker34 == null) {
try {
marker34 = mMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.img_4662878black)).draggable(false));
}
} catch (Exception e) {
}
hashMap.put(key1, marker34);
} else {
marker34.setPosition(location);
}
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
String key = dataSnapshot.getKey();
Log.d(TAG, "Location for '" + key + "' was removed.");
Marker marker = hashMap.get(key);
if (marker != null) {
marker.remove();
}
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Log.d(TAG, "Priority for " + dataSnapshot.getKey() + " was changed.");
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.w(TAG, "markerUpdateListener:onCancelled", databaseError.toException());
}
});
// код для удаления маркеров из firebase у текущего пользователя
handler1 = new Handler();
Runnable r1 = new Runnable() {
public void run() {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("Markers").child("Markers").child(firebaseAuth.getCurrentUser().getUid());
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
for (DataSnapshot single : child.getChildren()) {
try{
long cutoff = new Date().getTime() - TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
Log.d("TAG", String.valueOf(cutoff));
DatabaseReference markerRef = FirebaseDatabase.getInstance().getReference().child("Markers").child("Markers");
markerRef.child(firebaseAuth.getUid()).orderByChild("timeStamp").endAt(cutoff).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
data.getRef().removeValue();
}}
@Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
} catch (Exception e) {
e.printStackTrace();
}}};
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d("TAG1", databaseError.getMessage());
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
handler1.postDelayed(this, 1000);
}};
handler1.postDelayed(r1, 1000);
Ответы (1 шт):
Поскольку маркеры пользователей хранятся для каждого пользователя в отдельном узле, то для того, чтобы пользователь узнавал об удалениях маркеров других пользователей, он должен подписаться на события для детей для каждого узла, в котором хранятся маркеры пользователей.
Поясню на примере. Допустим у нас такая структура (я для простоты пропустил корневой узел):
{
"Markers": {
"user1": {
"marker1.1": { ... данные маркера ... },
"marker1.2": { ... данные маркера ... },
"marker1.3": { ... данные маркера ... }
},
"user2": {
"marker2.1": { ... данные маркера ... },
"marker2.2": { ... данные маркера ... }
},
"user3": {
"marker3.1": { ... данные маркера ... },
"marker3.2": { ... данные маркера ... }
}
}
}
Для того чтобы user1 узнавал об удалениях (да и других изменениях тоже) маркеров для пользователей user2 и user3 ему нужно подписаться на события изменения детей для узлов /Markers/user2 и /Markers/user3. Лучше всего это делать когда такой узел для пользователя создается:
DatabaseReference allUsersRef = rootRef1.child("Markers").child("Markers");
allUsersRef.addChildEventListener(new ChildEventListener {
@Override
public void onChildAdded(@NonNull DataSnapshot userDataSnapshot, @Nullable String s) {
final String otherUserId = userDataSnapshot.getKey();
userDataSnapshot.getRef().addChildEventListener(new new ChildEventListener {
@Override
public void onChildAdded(
@NonNull DataSnapshot markerDataSnapshot, @Nullable String s) {
final String markerId = markerDataSnapshot.getKey();
// это обработчик события, когда у пользователя с идентификатором
// otherUserId добавился маркер с идентификатором markerId
// тут можем добавить его в нашу коллекцию маркеров hashMap
// аналогично тому как сейчас это делается
...
hashMap.put(key, marker);
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
final String markerId = markerDataSnapshot.getKey();
// это обработчик события, когда у пользователя с идентификатором
// otherUserId удалился маркер с идентификатором markerId
// тут можем удалить его из нашей коллекции маркеров
Marker marker = hashMap.get(markerId);
if (marker != null) {
marker.remove();
}
}
});
}
// другие методы из ChildEventListener нужно определить тут
// и они будут пустыми
);