【问题标题】:Check if ID exists in Firebase Android检查 ID 是否存在于 Firebase Android 中
【发布时间】:2016-08-18 17:11:39
【问题描述】:

我正在编写一个 android 应用程序,我想检查一个键是否存在以避免重复值。我一直在调查,但看起来我只能添加侦听器,当我只想检查 ID 是否存在时。

以这个SO question为例,我想知道-JlvccKbEAyoLL9dc9_v是否存在。我该怎么做?

提前致谢。

【问题讨论】:

    标签: java android database firebase


    【解决方案1】:

    这种方法总是类似于我在这个关于 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 时,它们在统计上保证是唯一的。所以他们中的任何一个都无法创建与另一个相同的密钥。

    任何需要检查项目是否已存在的情况都可能存在竞争条件:如果两个客户端几乎同时执行此检查,则它们都不会找到值。

    【讨论】:

    • 非常感谢,它运行良好,但我担心您对比赛条件的建议。推送 ID 是什么意思?我不应该做这种检查吗?有没有其他方法可以避免重复 ID?
    • 我扩展了我的答案,以更清楚地涵盖推送 ID 与不同密钥类型的情况。
    【解决方案2】:

    RxJava 2:

    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);
    

    【讨论】:

    • 有趣的是,我以与您相同的方式实施此方法
    • @MohamedIbrahim :) 伟大的哈比比 :)
    • 这更有趣:)
    【解决方案3】:

    根据@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 以编程方式创建架构。我使用它是为了在不覆盖现有数据的情况下添加新数据。

    【讨论】:

      猜你喜欢
      • 2017-02-25
      • 2020-12-30
      • 2015-06-07
      • 2018-08-26
      • 2021-02-26
      • 2019-01-04
      • 2023-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多