【发布时间】:2016-08-18 17:11:39
【问题描述】:
我正在编写一个 android 应用程序,我想检查一个键是否存在以避免重复值。我一直在调查,但看起来我只能添加侦听器,当我只想检查 ID 是否存在时。
以这个SO question为例,我想知道-JlvccKbEAyoLL9dc9_v是否存在。我该怎么做?
提前致谢。
【问题讨论】:
标签: java android database firebase
我正在编写一个 android 应用程序,我想检查一个键是否存在以避免重复值。我一直在调查,但看起来我只能添加侦听器,当我只想检查 ID 是否存在时。
以这个SO question为例,我想知道-JlvccKbEAyoLL9dc9_v是否存在。我该怎么做?
提前致谢。
【问题讨论】:
标签: java android database firebase
这种方法总是类似于我在这个关于 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) { }
});
但请记住,Firebase 中存在推送 ID 以防止必须进行此类检查。当多个客户端生成推送 id 时,它们在统计上保证是唯一的。所以他们中的任何一个都无法创建与另一个相同的密钥。
任何需要检查项目是否已存在的情况都可能存在竞争条件:如果两个客户端几乎同时执行此检查,则它们都不会找到值。
【讨论】:
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));
}
在你的课堂上:
yourRepo.isYourObjectExists("-JlvccKbEAyoLL9dc9_v")
.subscribe(isExists -> {}, Throwable::printStackTrace);
【讨论】:
根据@Frank van Puffelen 的回答,这里有几行来查看在使用之前是否存在 ref - itself。
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) { }
});
}
在我的例子中,我有一个 Util 以编程方式创建架构。我使用它是为了在不覆盖现有数据的情况下添加新数据。
【讨论】: