I have inserted data and displaying it in List view as I am new to Firebase i dont know how to delete it.
My data format:
Code that i have tried to delete is:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
member.setName(list.get(position));
}
});
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String str = member.getName().substring(0,24);
if (str == "") {
Toast.makeText(Retreivedata.this, "plz select record to delete", Toast.LENGTH_LONG).show();
}else {
ref.child("Member").child(str).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
ref.child(str).removeValue();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Toast.makeText(Retreivedata.this,"Record is deleted",Toast.LENGTH_LONG).show();
Intent intent = new Intent(getApplicationContext(),Retreivedata.class);
startActivity(intent);
}
}
Suggest me what to set onclick of delete button.!!
I would suggest using firebase recycler adapter or android recycler view to load your data, but for your case this is what you can do:
Not the best way, but lets say you want to delete an item on click, and assuming that all names are different:
I assumed that member.getName() is giving you the name of the clicked item:
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//ref
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Member");
//Query
Query query = ref.orderByChild("name").equalTo(member.getName());
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
//remove
ds.getRef().removeValue();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
query.addValueEventListener(listener);
}
});
Related
So, I have this Firebase Structure.
I made an autocompletetext to get all child named "alimento".
That's OK!
But now, based on this "alimento" selection, I want to get all other childs in TextViews referent to this selection.
Is It possible? I don't know If I was clear enough.
This is my code: (I tried a lot of stuff, but all always return 0.00, so I won't put anything)
public class MainActivity extends AppCompatActivity {
private Button btnList, buttonAdicionar;
private AutoCompleteTextView autoCompleteTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnList = (Button) findViewById(R.id.btnList);
buttonAdicionar = (Button) findViewById(R.id.buttonAdicionar);
//Nothing special, create database reference.
final DatabaseReference database = FirebaseDatabase.getInstance().getReference();
//Create a new ArrayAdapter with your context and the simple layout for the dropdown menu provided by Android
final HRArrayAdapter<String> adapter = new HRArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line);
//Child the root before all the push() keys are found and add a ValueEventListener()
database.child("alimentos").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
adapter.clear();
//Basically, this says "For each DataSnapshot *Data* in dataSnapshot, do what's inside the method.
for (DataSnapshot suggestionSnapshot : dataSnapshot.getChildren()){
//Get the suggestion by childing the key of the string you want to get.
String autocomplete = suggestionSnapshot.child("alimento").getValue(String.class);
adapter.add(autocomplete);
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.acTV);
autoCompleteTextView.setAdapter(adapter);
autoCompleteTextView.setThreshold(1);
autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String alimento = (String) parent.getItemAtPosition(position);
Log.d("TAG", alimento);
Toast.makeText(getApplicationContext(), alimento, Toast.LENGTH_SHORT).show();
}
});
btnList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), FoodActivity.class));
}
});
buttonAdicionar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), NewAlimentoActivity.class));
}
});
}
}
This is an example that what I want (using SQL):
If you're asking how to get all child nodes with a specific value in their alimento property, that'd be something like:
database.child("alimentos")
.orderByChild("alimento")
.equalTo("Arroz, integral, cozido")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
String base = snapshot.child("base").getValue(String.class);
double baseValue = Double.parseDouble(base);
...
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
I want to replace kids/[id]/kidLimit/[new data]
So what I do is I make a spinner with kidName data, then with the selected item from that spinner I want to replace the data of kidLimit (with the same parent as the selected item from the spinner).
The first thing I do is to find the unique key of the selected item, then go to the kidLimit with that unique key to then use the setValue() method.
public class setLimit extends AppCompatActivity {
private DatabaseReference db;
private EditText etLimit;
private Button btnSetLimit;
private Spinner kidSpinner;
private String kidKey;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_limit);
etLimit = findViewById(R.id.et_limit);
btnSetLimit = findViewById(R.id.btn_confirm);
kidSpinner = findViewById(R.id.spinner_kid);
//PUTTING STRING LIST FROM FIREBASE TO SPINNER DROPDOWN STARTS HERE
db = FirebaseDatabase.getInstance().getReference().child("kids");
db.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final List<String> kid = new ArrayList<>();
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren()) {
String kidName = dataSnapshot1.child("kidName").getValue(String.class);
kid.add(kidName);
}
ArrayAdapter<String> kidNameAdapter = new ArrayAdapter<>(setLimit.this, android.R.layout.simple_spinner_item, kid);
kidNameAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
kidSpinner.setAdapter(kidNameAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//ENDS HERE
//ONCLICKLISTENER
btnSetLimit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
findId();
String newLimit = etLimit.getText().toString().trim();
db.child(kidKey).child("kidLimit").setValue(newLimit);
}
});
}
//FINDING KEY FROM THE SELECTED SPINNER ITEM
public void findId(){
String kidName = kidSpinner.getSelectedItem().toString();
db = FirebaseDatabase.getInstance().getReference().child("kids");
db.orderByChild("kidName").equalTo(kidName).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
kidKey = dataSnapshot1.getKey();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
So basically what I did was using the snapshot inside the onclick method to find the key. But when I check them on the log, it showed that the kidkey variable is null the first time I press the button, but after that it's not null anymore.
What can I to do so when I press the button, I can go to a specific child to replace it's data without getting any null pointer exception?
Here's the database that I use
When you do this
btnSetLimit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
findId();
String newLimit = etLimit.getText().toString().trim();
db.child(kidKey).child("kidLimit").setValue(newLimit);
}
});
findId(); is executed but you don't know when it will finish, so after that method is executed and waiting for data, this line
db.child(kidKey).child("kidLimit").setValue(newLimit);
will have kidKey with a null value because it has not been pulled yet from the database, so instead, you should move your code to the onDataChange() or make a new callback when all the asynchronous process finishes
btnSetLimit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
findId();
}
});
public void findId(){
String kidName = kidSpinner.getSelectedItem().toString();
String newLimit = etLimit.getText().toString().trim();
db = FirebaseDatabase.getInstance().getReference().child("kids");
db.orderByChild("kidName").equalTo(kidName).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
kidKey = dataSnapshot1.getKey();
}
db.child(kidKey).child("kidLimit").setValue(newLimit);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I am making a to-do app, indeed my first firebase app. I have successfully implemented everything with a single text view(todo) under the firebase UID, by creating an array of the push id that returns the push ID when an element is clicked in the List view.
Here was my previous data structure:
Old data Structure
I am stuck with the problem that how can I get the push IDs of elements so that I can reach them and display them in my ListView.
This is the structure that I am trying to fetch :
New data structure
Here is the code that I use for adding and deleting data in the old
Structure
public void Upload(View v) {
String userId = myRootRef.push().getKey();
firebaseUniqueID =mAuth.getCurrentUser().getUid();
todoToUpload=todoEditText.getText().toString();
myRootRef.child(firebaseUniqueID).child(userId).setValue(todoToUpload);
startActivity(new Intent(AddTodo.this,showTodo.class));
Here's the code I use for adding and deleting:
FirebaseAuth mAuth;
FirebaseDatabase mDataBase= FirebaseDatabase.getInstance();
DatabaseReference myRootRef=mDataBase.getReference();
DatabaseReference userRef;
ListView listView;int pos;
private ArrayAdapter<String> adapter;
ArrayList<String> mTodo=new ArrayList<>();
ArrayList<String> keysList = new ArrayList<>();
adapter=new ArrayAdapter<String>(this,R.layout.custom_list_layout,R.id.tood,mTodo);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
pos=position;
AlertDialog.Builder mBuilder=new AlertDialog.Builder(showTodo.this);
View mView=getLayoutInflater().inflate(R.layout.custom_dialog_show,null);
Todo=mView.findViewById(R.id.todo);
Delete=mView.findViewById(R.id.delete);
Done=mView.findViewById(R.id.done);
closer=mView.findViewById(R.id.dialog_close);
mBuilder.setView(mView);
final AlertDialog dailog=mBuilder.create();
myRootRef.child(firebaseUniqueID).child(keysList.get(position)).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
todoOpened=dataSnapshot.getValue(String.class);
Todo.setText(todoOpened);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(Done.isChecked())
{
mTodo.remove(pos);
adapter.notifyDataSetChanged();
//new code below
myRootRef.getRoot().child(firebaseUniqueID).child(keysList.get(pos)).removeValue();
keysList.remove(pos);
dailog.dismiss();
}
}
});
myRootRef.child(firebaseUniqueID)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot firebaseUniqueID : dataSnapshot.getChildren()) {
keysList.add(firebaseUniqueID.getKey());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
/*handle errors*/
}
});
userRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String value= dataSnapshot.getValue(String.class);
mTodo.add(value);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Here's the JSON file for the old and new structures
{
"Z2H2ZkX56fYv3WKxE3a3nCaa8Q63" : {
"-LNPyZIkX8-uDDGeX-pN" : {
"Time" : "22:56",
"Todo" : "play"
},
"-LNPze7ppG1L0qFukZO-" : {
"Priority" : "High",
"Time" : "22:56",
"TimeSet" : "09:56",
"Todo" : "play till the sun goes down"
},
"-LNPzhBDDtHv_XSIERX_" : {
"Priority" : "High",
"Time" : "22:56",
"TimeSet" : "09:56",
"Todo" : "play till the sun goes ddawdawdawdwown"
}
}
}
{
"Z2H2ZkX56fYv3WKxE3a3nCaa8Q63" : {
"-LNQRCZSsYVPqn0tWghZ" : "play in the evening",
"-LNQRrLliVSxWBHcEIrv" : "I want to shine like a sun"
}
}
You get the key of a DataSnapshot by calling its getKey() method. So for example:
public void onDataChange(DataSnapshot dataSnapshot) {
todoOpened=dataSnapshot.getValue(String.class);
String key = dataSnapshot.getKey();
Todo.setText(key + ": "+ todoOpened);
}
you can display list as per your new structure dsplayed in :https://i.stack.imgur.com/E4DXI.png
FirebaseRecyclerOptions<Messages> options =
new FirebaseRecyclerOptions.Builder<"Your Class Name">()
.setQuery(mMessageThread.child("messages").limitToLast(500), "Your Class Name".class)
.setLifecycleOwner(this)
.build();
use this with firebase adapter.
Then get ToDo text and display it.
I'm using the following code to fill a list with data from a child within firebase database. The list is filled successfully, but I've got an issue: FirebaseListAdapter is being called multiple times before stopping, what does not occur when I use it in other activities.
One weird thing is that when I click a specific listView item, data from another item is passed through my openChat intent, what makes wrong data be retrieved to the chat activity I open. It seems that the calling multiple times thing is messing all the data.
Can someone point out what might be wrong with my code and/or what I must do to optimize it?
//database references
chatsRef = FirebaseDatabase.getInstance().getReference().child("chats").child(mAuth.getCurrentUser().getUid()); //the children of this are other users IDs
usersRef = FirebaseDatabase.getInstance().getReference().child("users");
////////// code for populateView I use within FirebaseListAdapter ///////////
FirebaseListAdapter<ChatUsers> firebaseListAdapter = new FirebaseListAdapter<ChatUsers>(getActivity(), ChatUsers.class, R.layout.item_user_listing, chatsRef) {
protected void populateView(View view, ChatUsers chatUsers, int position) {
TextView nameChatItemList = (TextView) view.findViewById(R.id.nameChatItemList);
id_other_user = getRef(position).getKey();
usersRef.child(id_other_user).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//for (DataSnapshot ds : dataSnapshot.getChildren())
Toast.makeText(mActivity, dataSnapshot.getValue().toString(), Toast.LENGTH_SHORT).show();
name = dataSnapshot.child("name").getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent openChat= new Intent(getActivity().getApplicationContext(), Chat.class);
openChat.putExtra("iduser_chat", id_outro_usuario);
openChat.putExtra("name_user_chat", name);
startActivity(openChat);
}
});
}
}
EDIT Changes implemented as suggested by Farmaan
FirebaseListAdapter<ChatUsers> firebaseListAdapter = new FirebaseListAdapter<ChatUsers>(getActivity(), ChatUsers.class, R.layout.item_user_listing, ChatsRef) {
#Override
protected void populateView(View view, ChatUsers chatUsers, int position) {
TextView nomeImageChatItemList = (TextView) view.findViewById(R.id.nomeChatItemList);
String id_other_user = getRef(position).getKey();
usersRef.child(id_other_user).addListenerForSingleValue(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue().toString();
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
usersRef.child(id_other_user).addListenerForSingleValue(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue().toString();
Intent openChat = new Intent(getActivity().getApplicationContext(), Chat.class);
openChat.putExtra("iduser_chat", id_other_user);
openChat.putExtra("nameuser_chat", name);
startActivity(openChat);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
};
Since id_other_user and name are the class level field and you are updating it every time you populate the view.So the last view which is populated will decide the user id and the name.That's wrong with your code.
chatsRef = FirebaseDatabase.getInstance().getReference().child("chats").child(mAuth.getCurrentUser().getUid()); //the children of this are other users IDs
usersRef = FirebaseDatabase.getInstance().getReference().child("users");
////////// code for populateView I use within FirebaseListAdapter ///////////
protected void populateView (View view, ChatUsuarios chatUsuarios,int position){
TextView nameChatItemList = (TextView) view.findViewById(R.id.nameChatItemList);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String id_other_user = getRef(position).getKey();
usersRef.child(id_other_user).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//for (DataSnapshot ds : dataSnapshot.getChildren())
String name = dataSnapshot.child("name").getValue().toString();
Intent openChat = new Intent(getActivity().getApplicationContext(), Chat.class);
openChat.putExtra("iduser_chat", id_other_user);
openChat.putExtra("name_user_chat", name);
startActivity(openChat);
Toast.makeText(mActivity, dataSnapshot.getValue().toString(), Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
I have to use custom RecyclerView because I don't want to update to list real time.
How do I get an id if I want to go into the details of the data? As in FirebaseRecyclerAdapter.
final String uid = getRef(position).getKey();
I added postId, my posts table, and I wrote the following code. But when click on the image, it goes to the last added image to the list. And when I click upVote, every item goes crazy and they click upVote too.
First, am I on the right track to update the list only when I want to? Second, why is everything going crazy?
PostAdapter
public PostRecyclerAdapter(Context context, Query query) {
this.context = context;
this.query = query;
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
posts.clear();
for (DataSnapshot data : dataSnapshot.getChildren()) {
posts.add(data.getValue(Post.class));
}
Collections.sort(posts, new Comparator<Post>() {
#Override
public int compare(Post o1, Post o2) {
Long a = o1.getCreatedDate();
Long b = o2.getCreatedDate();
if (a < b) {
return -1;
} else if (a == b) {
return 0;
} else {
return 1;
}
}
});
notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onBindViewHolder(final PostViewHolder viewHolder, int position) {
model = posts.get(position);
postId = model.getPostId();
viewHolder.setTitle(model.getTitle());
viewHolder.setImage(context, model.getImage());
viewHolder.setUpVote(postId);
viewHolder.imvImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, SinglePostActivity.class);
intent.putExtra(Enums.PostKeys.postId.getValue(), postId);
context.startActivity(intent);
}
});
viewHolder.imbUpVote.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!checkAuthUser()) {
context.startActivity(new Intent(context, SignUpActivity.class));
return;
}
processVote = true;
Singleton.getDbPostDownVote(postId).child(postId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (processVote == true) {
if (dataSnapshot.hasChild(getUserId())) {
Singleton.getDbPostDownVote(postId).child(postId).child(getUserId()).removeValue();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Singleton.getDbPostUpVote(postId).child(postId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (processVote == true) {
if (dataSnapshot.hasChild(getUserId())) {
Singleton.getDbPostUpVote(postId).child(postId).child(getUserId()).removeValue();
processVote = false;
} else {
Singleton.getDbPostUpVote(postId).child(postId).child(getUserId()).setValue(0);
processVote = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
PostViewHolder:setUpVote
public void setUpVote(final String postId) {
Singleton.getDbPostUpVote(postId).child(postId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild(getUid())) {
imbUpVote.setImageResource(R.drawable.vote_up_active);
} else {
imbUpVote.setImageResource(R.drawable.vote_up_passive);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
How do I get an id if I want to go into the details of the data?
Usually the id is a node in your db. As you can see in
final String uid = getRef(position).getKey();
getKey returns tha value of the node in db.
In your case to avoid sorting the list with comparator i would just structure the data like so:
20170111
title : some title
text : some text
20170112
title : some title
text : some text
This way data is going to be sorted by the nodes, which is the date, by Firebase. If you want to be more precise you can also add hours and minutes.
First, am I on the right track to update the list only when I want to?
No.
Calling addValueEventListener() is going to trigger the code inside the listener each time the value in your db changes. In other words, its realtime.
Use addListenerForSingleValueEvent() insted. It fires only once.
Second, why is everything going crazy?
Very important thing about onDataChange() is that it fires not only when the value changes but also the first time you set the listener. That is why everything is getting voted up when you click one item.