java - 在 Realtime Firebase 中从数据库检索数据时出现问题

标签 java android firebase-realtime-database

我目前正在制作一个餐厅菜单应用程序,并且我遵循了一些在线教程,其中该人能够在他的应用程序中显示他的实时 Firebase 中的内容。目前,我可以通过我的应用程序向数据库添加新的菜单项(反射(reflect)在我的数据库本身中),但在应用程序本身中,我实际上无法检索数据库。我的代码有错误吗?任何帮助将不胜感激!

'''

EditText editTextItemName, editTextPrice;
Spinner spinnerSection;
ListView ListViewItems;
Button buttonMainMenu, buttonAddItem;
List<Items> listItems;

DatabaseReference databaseItems;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);

    databaseItems = FirebaseDatabase.getInstance().getReference("items");
    listItems = new ArrayList<>();
    //ItemActivity ItemAdapter = new ItemActivity(Main2Activity.this,listItems);//
    //ListViewItems.setAdapter(ItemAdapter);//

    buttonMainMenu = (Button) findViewById(R.id.buttonMainMenu);
    buttonMainMenu.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            openMainActivity();
        }
    });
    buttonAddItem = (Button) findViewById(R.id.buttonAddItem);
    editTextItemName = (EditText) findViewById(R.id.editTextItemName);
    editTextPrice = (EditText) findViewById(R.id.editTextPrice);
    spinnerSection = (Spinner) findViewById(R.id.spinnerSection);
    ListViewItems = (ListView) findViewById(R.id.ListViewItems);
    buttonAddItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            addItems();
        }
    });

    ListViewItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
            Items Items = listItems.get(i);
            showUpdateDeleteDialog(Items.getItemsId(), Items.getItemName());
            return true;

        }
    });
}
    @Override
    protected void onStart() {
        super.onStart();


        databaseItems.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                listItems.clear();
                for (DataSnapshot itemSnapshot : dataSnapshot.getChildren()) {
                    Items items = itemSnapshot.getValue(Items.class);
                    listItems.add(items);
                }
                ItemActivity adapter = new ItemActivity(Main2Activity.this, listItems);
                ListViewItems.setAdapter(adapter);
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                throw databaseError.toException();

            }
        });
}

private void addItems(){
    String Name = editTextItemName.getText().toString().trim();
    String Price = editTextPrice.getText().toString().trim();
    String Section = spinnerSection.getSelectedItem().toString();

    if (ItemName.isEmpty()) {
        editTextItemName.setError("Item Name can't be empty");
        editTextItemName.requestFocus();
        return;
    }

    if (Price.isEmpty()) {
        editTextPrice.setError("Price can't be empty");
        editTextPrice.requestFocus();
        return;
    } else {
        String id = databaseItems.push().getKey();
        Items items = new Items(id, ItemName, Section, Price);
        databaseItems.child(id).setValue(items);
        Toast.makeText(this, "Item Added", Toast.LENGTH_LONG).show();
    }
}
public void openMainActivity(){
    Intent intent = new Intent(this,MainActivity.class);
    startActivity(intent);
}

private void showUpdateDeleteDialog(final String ItemsId, String ItemName) {

    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
    LayoutInflater inflater = getLayoutInflater();
    final View dialogView = inflater.inflate(R.layout.dialog_update_items, null);
    dialogBuilder.setView(dialogView);

    final EditText editTextItemName = (EditText) dialogView.findViewById(R.id.editTextItemName);
    final EditText editTextPrice = (EditText) dialogView.findViewById(R.id.editTextPrice);
    final Spinner spinnerSection = (Spinner) dialogView.findViewById(R.id.spinnerSection);
    final Button buttonUpdateItem = (Button) dialogView.findViewById(R.id.buttonUpdateItem);
    final Button buttonDeleteItem = (Button) dialogView.findViewById(R.id.buttonDeleteItem);

    dialogBuilder.setTitle(ItemName);
    final AlertDialog b = dialogBuilder.create();
    b.show();

    buttonUpdateItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String ItemName = editTextItemName.getText().toString().trim();
            String ItemPrice = editTextPrice.getText().toString().trim();
            String ItemSection = spinnerSection.getSelectedItem().toString();

            if (ItemName.isEmpty()) {
                editTextItemName.setError("Item Name can't be empty");
                editTextItemName.requestFocus();
                return;
            }

            if (ItemPrice.isEmpty()) {
                editTextPrice.setError("Price can't be empty");
                editTextPrice.requestFocus();
                return;
            }
            else updateItems(ItemsId, ItemName, ItemSection, ItemPrice);
        }
    });

    buttonDeleteItem.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            deleteItems(ItemsId);
        }
    });
}



private boolean updateItems(String id, String Name, String Section, String Price){

    DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("items").child(id);

    Items items = new Items(id, Name, Section, Price);

    databaseReference.setValue(items);

    Toast.makeText(this, "Item Updated", Toast.LENGTH_LONG).show();

    return true;
}

private void deleteItems(String ItemsId) {

    DatabaseReference drItems = FirebaseDatabase.getInstance().getReference("items").child(ItemsId);

    drItems.removeValue();

    Toast.makeText(this, "Item Deleted", Toast.LENGTH_LONG).show();
}

} '''

JSON Tree

Run tab when this activity is opened

最佳答案

这将是一段漫长的旅程,请坐下 🙂。

首先,我想用自然数替换数据库 ID。 为此,您需要更改添加新项目的方式:

创建一个类AddNewItems:

package com.<package-name>; 

public class AddNewItems {

    private String name;
    private String section;
    private String price;
    private int id;

    public AddNewItems() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSection() {
        return section;
    }

    public void setSection(String section) {
        this.section = section;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price; 
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}   

现在让我们回到添加新项目的 MainActivity。将您的 addItem() 修改为:

AddNewItems addNewItems; //Add this below your DatabaseReference databaseItems;

private void addItems(){
    String Name = editTextItemName.getText().toString().trim();
    String Price = editTextPrice.getText().toString().trim();
    String Section = spinnerSection.getSelectedItem().toString();

    String lastItemIdFetched; //This will check ID of last item and assign new value to new items.
    Int lastIdInt; //For adding 1, we need to convert to int
    //Make sure you read the note at bottom

    if (ItemName.isEmpty()) {
        editTextItemName.setError("Item Name can't be empty");
        editTextItemName.requestFocus();
        return;
    }

    if (Price.isEmpty()) {
        editTextPrice.setError("Price can't be empty");
        editTextPrice.requestFocus();
        return;
    } else {
        //For sake of automating new ID
        DatabaseReference addItemIdRef;
        addItemIdRef = FirebaseDatabase.getInstance().getReference("itemIDs");

        addItemIdRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                try {
                    lastItemIDFetched = dataSnapshot.child("lastItemID").getValue().toString();
                    lastIdInt = Integer.parseInt(lastItemIdFetched);
                    lastIdInt = lastIdInt + 1;
                }catch (Throwable e){
                    Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        // Adding data in database
        addNewItems.setName(Name);
        addNewItems.setSection(Section);
        addNewItems.setPrice(Price);
        addNewItems.setId(lastIdInt);

        databaseItems.child(lastIdInt).setValue(addNewItems);
        Toast.makeText(getApplicationContext(), "New Item has been added to your menu.", Toast.LENGTH_SHORT).show();

        // We also need to value of last ID in database. So do this.
        Map<String, Object> updateNewID = new HashMap<>();
        updateNewID.put("lastItemID", lastIdInt);

        addItemIdRef.child("lastItemID).updateChildren(updateNewID).addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            Toast.makeText(getApplicationContext(), "Success on updating", Toast.LENGTH_LONG).show();
            }
        }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
            }
         });

        //WE have successfully updated the last item ID
    }
}

注意:当我们从数据库中获取lastItemID时。没有代码来验证这是否是第一项,并且可能会导致崩溃。如果不想增加代码(它已经是),请从控制台手动创建以下代码。

enter image description here

如图所示创建一个新节点并将值设置为 0,因此当您添加第一个项目时,它的 ID 将为 1。

现在回到检索部分,在您的 onStart() 函数中执行此操作: 让我们使用列表来完成:

//Create a listView in XML also and define it in MainActivity.
//ListView listItems = (ListView) findViewById(R.id.resource_name); 
//First create a list and adapter 
ArrayList<String> listItems=new ArrayList<String>();
ArrayAdapter<String> adapter;

DatabaseReference fetchItemsRef;
fetchItemsRef = FirebaseDatabase.getInstance().getReference("items");

DatabaseReference getTotalNumberOfItemsRef;
getTotalNumberOfItemsRef = FirebaseDatabase.getInstance().getReference("itemIDs");

Int i, totalNumberOfItems;
//I've again added this to check number items available. 

//Put this in your `onStart()` function.
adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listItems);
setListAdapter(adapter);

//Get total number of items:           
getTotalNumberOfItemsRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

        try {
            totalNumberOfItems = Integer.parseInt(dataSnapshot.child("lastItemID").getValue().toString());            
            }catch (Throwable e){
                 Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
            }
        }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {

    }
});

//Now let's fetch the data from Firebase using a `for loop`: 
for(int i=0; i<=totalNumberOfItems; i++){
    String currentItemName = "item"+i;

    fetchItemsRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            try {
                currentItemName = dataSnapshot.child(i).getValue().toString();            
            }catch (Throwable e){
                    Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

    listItems.add(currentItemName);
    adapter.notifyDataSetChanged();
}

现在你必须确保数据库中的所有项目都是连续整数,例如 1,2,3... 并且不能是像 1,2,4,5,8... 这样的,因为没有代码可以处理空对象。您可以稍后使用条件语句添加它。

关于java - 在 Realtime Firebase 中从数据库检索数据时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61321557/

相关文章:

android - 如何使用 ImageDecoder 获取可变位图?

android - FirebaseListAdapter 字母顺序

android - 从android中的firebase数据库中检索 child

java - 在 Java 中有条件地返回对象(没有迭代器)

java - 如何获取 OnClickListener 的正确上下文?

java - write(byte[],int,int) 方法是如何工作的?

android - 如何从我的 PC 浏览器使用 android 发送短信?

javascript - 如何从 map 对象返回一个字符串并发送到 firebase?

java - log4j2 在 Hadoop 二进制文件中给出 : java. io.IOException : Could not locate executable null\bin\winutils. exe

java - 响应中的spring和mod_jk jsp源码