简体   繁体   中英

Issues retrieving data from database in Realtime Firebase

I'm currently making a restaurant menu application and I followed some online tutorials where the guy was able to display what was in his realtime firebase in his application. Currently, I am able to add new menu items to my database through my application (reflected in my database itself) but within the app itself, I can't actually retrieve the database. Are there any errors in my code? Any help would be greatly appreciated!

'''

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 树

Run tab when this activity is opened

It's going to be long journey, take a seat.

First of all I would like to replace the Database IDs with Natural Numbers. To do so you need to change the way you add your new items:

Create a class 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;
    }
}   

Now let's get back to your MainActivity from where you add new items. Modify your addItem() to this:

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
    }
}

NOTE: As we are fetching the lastItemID from the database. There is no code to verify if this is first item or not and might lead to a crash. If didn't wanted to increase the code (which it already is) so please create the following manually from the console.

在此处输入图像描述

Create a new node as shown and set the value to 0, so when you add first item, it's ID will be 1.

Now coming back to the retrieving part, do this in your onStart() function: Let's do it using a list:

//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();
}

Now you must make sure all the items in your database are continuous integers like 1,2,3... and must not be like 1,2,4,5,8... because there is no code which can handle null objects. You can add that using conditional statements later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM