Reputation: 2413
I am writing an android app and I want to check if a key exists in order to avoid duplicate values. I´ve been investigating but it looks that all I can add is listeners, when I just want to check if an ID exists or not already.
Taking this SO question as an example, I would like to know if -JlvccKbEAyoLL9dc9_v
exists. How can I do this?
Thanks in advance.
Upvotes: 4
Views: 10999
Reputation: 16619
public static Observable<Boolean> observeExistsSingle(final DatabaseReference ref) {
return Observable.create(emitter ->
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
emitter.onNext(dataSnapshot.exists());
emitter.onComplete();
}
@Override
public void onCancelled(DatabaseError databaseError) {
emitter.onError(databaseError.toException());
}
}));
}
public Observable<Boolean> isYourObjectExists(String uid) {
return observeExistsSingle(databaseReference.child(uid));
}
In your class:
yourRepo.isYourObjectExists("-JlvccKbEAyoLL9dc9_v")
.subscribe(isExists -> {}, Throwable::printStackTrace);
Upvotes: 1
Reputation: 12073
Based on @Frank van Puffelen's answer, here's a few lines to see if a ref - itself - exists before using it.
public void saveIfRefIsAbsent(DatabaseReference firebaseRef) {
DatabaseReference parentRef = firebaseRef.getParent();
String refString = firebaseRef.toString();
int lastSlashIndex = refString.lastIndexOf('/');
String refKey = refString.substring(lastSlashIndex + 1);
parentRef.child(refKey).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
// TODO: handle the case where the data already exists
}
else {
// TODO: handle the case where the data does not yet exist
}
}
@Override
public void onCancelled(FirebaseError firebaseError) { }
});
}
In my case I have a Util to create the schema programmatically. I use this in order to add new data without overwriting existing data.
Upvotes: 0
Reputation: 598951
The approach will always be similar to what I wrote in this answer about JavaScript: Test if a data exist in Firebase
ref.child("-JlvccKbEAyoLL9dc9_v").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
// TODO: handle the case where the data already exists
}
else {
// TODO: handle the case where the data does not yet exist
}
}
@Override
public void onCancelled(FirebaseError firebaseError) { }
});
But keep in mind that push ids in Firebase exist to prevent having to do this sort of check. When multiple clients generate push ids, they are statistically guaranteed to be unique. So there's no way one of them can create the same key as another.
Any case where you need to check if an item already exists is likely to have race conditions: if two clients perform this check almost at the same time, neither of them will find a value.
Upvotes: 13