【问题标题】:Android Firebase database, checking if db contains the object [duplicate]Android Firebase数据库,检查db是否包含对象[重复]
【发布时间】:2018-07-24 17:23:03
【问题描述】:

我使用 Firebase DB 作为我的 Android 应用程序的数据库。我需要检查 db 是否包含具有名称的对象,该名称为用户提供。如果是,我将引用保存到它并加载数据,esle - 显示有关不正确的对象名称的信息。

作为我使用的示例: Firebase querying data

代码:

private void setListReferance(){
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);

    builder.setTitle(Config.ADDLIST);

            // Set up the input
            final EditText input = new EditText(this);
            // Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
            input.setInputType(InputType.TYPE_CLASS_TEXT);
            builder.setView(input);

            // Set up the buttons
            builder.setPositiveButton(Config.OK, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String listName = input.getText().toString();
                    boolean correctName = checkListName(shoplistsRef, listName);

                    if(correctName){
                        listRef = shoplistsRef.child(listName);
                        myAdapter.setItemsListRef(listRef);
                        myAdapter.notifyDataSetChanged();
                        firebaseUpdate();
                    }
                    else{
                        String messege = "Niepoprawna nazwa listy";
                        Toast.makeText(MainActivity.this,
                                messege, Toast.LENGTH_LONG).show();
                    }
                }
            });
            builder.setNegativeButton(Config.CANCEL, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

            builder.show();
}

检查 db 是否包含的方法。对于测试,我添加了祝酒词。

private boolean checkListName(DatabaseReference ref, String listName){
    boolean[] result = new boolean[1];
    Query query = ref.child(listName);

    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            if (dataSnapshot.exists()) {
                Toast.makeText(MainActivity.this,
                        ref.toString(), Toast.LENGTH_LONG).show();


                    Toast.makeText(MainActivity.this,
                            dataSnapshot.getValue(String.class), Toast.LENGTH_LONG).show();

                result[0] = true;
            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    return result[0];
}

问题是当我写正确的名字(数据库有)时,第一个 toast 从 else 块 setListReferance() 显示(根本不应该显示),然后两个 toast 从 if (dataSnapshot.exists()){}

为什么会这样?我认为同步和异步方法存在问题,但我不知道如何解决。

【问题讨论】:

  • 检查这里给出的答案stackoverflow.com/questions/34486417/… ...
  • 您不能在onDataChange() 方法内部设置result[0],然后在外部简单地使用它。因此,请检查副本以了解您为什么会出现这种行为以及如何使用自定义回调来解决此问题。

标签: java android firebase firebase-realtime-database


【解决方案1】:

Firebase 是一种异步设计。查看 Google 文档Read and Write using Firebase

Firebase 数据被写入 FirebaseDatabase 引用,并通过将异步侦听器附加到该引用来检索。侦听器会在数据的初始状态触发一次,并且在数据更改时再次触发。

这样做:“boolean[] result = new boolean1;”由于异步实现,将无法工作。当然有时你可能会因为某种原因而幸运,你会看到价值更新,但它是不一致的。原因是,您在声明该值的同时,您的数据包竞相到 firebase 数据库以获取它的值,那么这就是发生混乱的地方,值被更新并且 然后 数据包到达回来但是太晚了,值已经更新了。

一种解决方法是使用回调监听器:

public class FireBaseHandler{
 private FirebaseDatabase mFirebaseDatabase;
 private DatabaseReference mFireBaseReference;
 private long firebaseKeyCount;

 public FireBaseHandler(){
  mFirebaseDatabase = FirebaseDatabase.getInstance();
  mFireBaseReference = mFirebaseDatabase.getReference();
  firebaseKeyCount = 0;
 }

 public void readAllKeysFireBase(final OnFireBaseListener listener){
 mFireBaseReference.addValueEventListener(new ValueEventListener() {
  @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
   for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
    for(DataSnapshot key : snapshot.getChildren()){
     Log.d("getKeys(): ", key.getKey()); //gets the keys from firebase
     firebaseKeyCount = listener.keyCount(key.getChildrenCount());
    }//foreach_snapshot
   }//foreach_dataSnapshot
  }//onDataChange
  @Override public void onCancelled(@NonNull DatabaseError databaseError) {
   Log.w("onCancelled()", "Failed to read value.", databaseError.toException());
  }//onCancelled
 });//mFireBaseReference
}//readAllKeysFireBase
}//FireBaseHandler end of class

public interface OnFireBaseListener{
 long keyCount(long data);
}

【讨论】:

    猜你喜欢
    • 2019-08-24
    • 2020-11-29
    • 1970-01-01
    • 2020-06-07
    • 2022-11-09
    • 2013-10-13
    • 2019-01-12
    • 2018-11-21
    • 2017-03-19
    相关资源
    最近更新 更多