Update specific node in database - java

Thanks for the previous help, I managed to write to the firebase database, the problem now is that I can't take the specific node to edit.
When opening an element from a recyclerview and obtaining the data and modifying the interno value and pressing update button , the database checks it but saves it outside the uid of the selected cow. You can see it better in the image.
This is the code where im trying to do the update. I've been testing and may have missing or leftover code, sorry. I do it only with interno as a test to later add the rest of the keys
private void Update() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Vacas");
String key = ref.child("Vacas").push().getKey();
Cow cow = new Cow();
Map<String, Object> updates = new HashMap<String, Object>();
updates.put("interno", tvinterno.getText().toString());
ref.updateChildren(updates);
}
I am not taking the reference correctly, I hope you can help me solve this problem, thank you
EDIT
I am using the database in a recyclerview, you can see in the image, when I click on a cow, a new activity opens with all the information in the database, this is where I am interested in editing the values ​​( Attached image).
I want to edit the values ​​based on the selected cow from the app, this is where I don't know if the solution you proposed to Mr. HaroldSer and Mr. Arup will work
EDIT 2
This is how I set the values ​​in the Edit activity
in my adapter in the onBindViewHolder, I send them to the Edit activity through an intent
#Override
public void onBindViewHolder(#NonNull final cowviewHolder holder, int position) {
final Cow vacaslist = vacas.get(position);
holder.textViewinterno.setText(vacaslist.interno);
holder.textViewsiniiga.setText(vacaslist.siniiga);
String url= vacaslist.getUrl();
if (url == null|| url.isEmpty()){
holder.imageviewrec.setImageResource(R.drawable.ic_imageinf);
} else {
Picasso.get().load(vacaslist.getUrl()).error(R.drawable.ic_imageinf).into(holder.imageviewrec);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), Cowdetail.class);
intent.putExtra("keyint", vacaslist.getInterno());
intent.putExtra("keysin", vacaslist.getSiniiga());
intent.putExtra("madre", vacaslist.getMadre());
intent.putExtra("padre", vacaslist.getPadre());
intent.putExtra("nacimiento", vacaslist.getNacimiento());
intent.putExtra("toro", vacaslist.getToro());
intent.putExtra("estatus", vacaslist.getEstatus());
intent.putExtra("inseminacion", vacaslist.getInseminacion());
intent.putExtra("notas", vacaslist.getNotas());
intent.putExtra("img", url);
v.getContext().startActivity(intent);
}
});
}
in this way I set them in Edit activity (Cowdetail)
public class Cowdetail extends AppCompatActivity {
EditText tvinterno, tvsiniiga, tvpadre, tvmadre, tvnacimiento, tvinseminacion, tvtoro, tvestatus, tvnotas;
AppCompatImageView tvimage;
Button tvbutton;
String cow_key;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detailcow);
tvinterno = (EditText) findViewById(R.id.tvinterno);
tvsiniiga = (EditText) findViewById(R.id.tvsiniiga);
tvpadre = (EditText) findViewById(R.id.tvpadre);
tvmadre = (EditText) findViewById(R.id.tvmadre);
tvnacimiento = (EditText) findViewById(R.id.tvnacimiento);
tvinseminacion = (EditText) findViewById(R.id.tvinsemincion);
tvtoro = (EditText) findViewById(R.id.tvtoro);
tvestatus = (EditText) findViewById(R.id.tvestatus);
tvnotas = (EditText) findViewById(R.id.tvnotas);
tvimage = (AppCompatImageView) findViewById(R.id.tvimage);
tvbutton = findViewById(R.id.actualizar);
String vpadre = "";
String vmadre = "";
String vinterno = "";
String vsiniiga = "";
String vnacimiento = "";
String vinseminacion = "";
String vtoro = "";
String vestatus = "";
String vnotas = "";
String vurl;
Bundle extras = getIntent().getExtras();
if (extras !=null);
vinterno = extras.getString("keyint");
vsiniiga = extras.getString("keysin");
vmadre = extras.getString("madre");
vpadre = extras.getString("padre");
vnacimiento = extras.getString("nacimiento");
vinseminacion = extras.getString("inseminacion");
vtoro = extras.getString("toro");
vestatus = extras.getString("estatus");
vnotas = extras.getString("notas");
String image = extras.getString("img");
if (image == null|| image.isEmpty()){
tvimage.setImageResource(R.drawable.ic_imageinf);
} else {
Picasso.get().load(image).fit().centerCrop().into(tvimage);
}
tvpadre.setText(vpadre);
tvinterno.setText(vinterno);
tvsiniiga.setText(vsiniiga);
tvmadre.setText(vmadre);
tvnacimiento.setText(vnacimiento);
tvinseminacion.setText(vinseminacion);
tvtoro.setText(vtoro);
tvestatus.setText(vestatus);
tvnotas.setText(vnotas);
tvbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Update();
}
});
}
private void Update() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Vacas");
String key = ref.child("interno").getKey();
Cow cow = new Cow();
Map<String, Object> updates = new HashMap<String, Object>();
updates.put("interno", tvinterno.getText().toString());
ref.child(key).updateChildren(updates)
}
}
EDIT 3
this is how i add the node_id to onDataChange
mReferenceCow.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
vacas.clear();
for (DataSnapshot snapshot1 :
snapshot.getChildren()) {
Cow vaca = snapshot1.getValue(Cow.class);
vaca.setNode_id(snapshot.getKey());
vacas.add(vaca);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
The rest of the code you told me, I did it as is, except in the ref, because if I don't add -- " " -- to the node_id it marks an error
ref.child("node_id").updateChildren(updates)
this keeps happening
EDIT 4
With this code i can get the interno value and edit it from the app. But now the problem is when I enter from the app to edit the interno value of a single node, it is changed in all nodes
private void Update() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
reference.child("Vacas").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot datas: snapshot.getChildren()){
String key = datas.getKey();
Map<String, Object> update = new HashMap<String, Object>();
update.put("interno", tvinterno.getText().toString());
FirebaseDatabase.getInstance().getReference().child("Vacas")
.child(key).updateChildren(update);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}

You just need to update below code:
from:
ref.updateChildren(updates);
to:
ref.child(cow_key).updateChildren(updates);
where cow_key is one of the cow's key such as: "1717" or "1836".

If I'm not wrong you want to update your existing data in firebase right? If this is the case then
I am not taking the reference correctly Yes
Try this
EDIT
Add node_id field to vacaslist pojo class and generate Getter and Setter.
Now add vacaslist.setNode_id(snapshot.getKey()); in onDataChange where you are setting data for recycler view.
Add this intent.putExtra("node_id", vacaslist.getNode_id()); to your onBindViewHolder
Get the value in EditActivity String node_id = extras.getString("node_id");
First take the reference
DatabaseReference dRef = FirebaseDatabase.getInstance().getReference().child("Vacas");
For example Now I want to update interno in 1717 child node then I'll do in this way
private void Update() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Vacas");
HashMap<String, Object> updates = new HashMap();
updates.put("interno", tvinterno.getText().toString());
dRef.child(node_id).updateChildren(updates);
}

Finally, I changed the EditActivity for a Dialogplus in onBindViewHolder of my AdapterActivity. Here i setted my information and using Hashmap for update the specific nodes.
#Override
public void onClick(View v) {
final DialogPlus dialogPlus = DialogPlus.newDialog(holder.imageviewrec.getContext())
.setContentHolder(new com.orhanobut.dialogplus.ViewHolder(R.layout.dialog_detail))
.setExpanded(true, 2000)
.create();
View myview = dialogPlus.getHolderView();
final EditText interno = myview.findViewById(R.id.dinterno);
final EditText siniiga = myview.findViewById(R.id.dsiniiga);
interno.setText(model.getInterno());
siniiga.setText(model.getSiniiga());
dialogPlus.show();
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Map<String, Object> map = new HashMap<>();
map.put("interno", interno.getText().toString());
map.put("siniiga", siniiga.getText().toString());
FirebaseDatabase.getInstance().getReference().child("Vacas")
.child(getRef(position).getKey()).updateChildren(map)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dialogPlus.dismiss();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
dialogPlus.dismiss();
}
});
}
});
}
});

Related

What is a better alternative to valueEventListener for retrieving data from firebase database?

My Firebase database is like that -
users -
first user ID
- name - "abc"
- image - "url"
- one_word - "abc"
following -
first user ID -
second User ID - "0"
Following node shows that First user is following second user.
Here is my code -
#Override
protected void onStart() {
super.onStart();
imageView.setVisibility(View.GONE);
FirebaseRecyclerAdapter<followers_following_class,following_Adapter>firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<followers_following_class, following_Adapter>
(
followers_following_class.class,
R.layout.find_friend_card,
following_Adapter.class,
databaseReference
) {
#Override
protected void populateViewHolder(final following_Adapter viewHolder, final followers_following_class model, int position) {
final String user_id = getRef(position).getKey();
users.child(user_id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final String name = dataSnapshot.child("name").getValue().toString();
final String image = dataSnapshot.child("image").getValue().toString();
final String line = dataSnapshot.child("line").getValue().toString();
final String wins = dataSnapshot.child("one_word").getValue().toString();
viewHolder.setName(name);
viewHolder.setImage(following.this,image);
viewHolder.setLine(line);
viewHolder.setOne_word(wins);
if(getItemCount() == 0){
imageView.setVisibility(View.VISIBLE);
}
viewHolder.vieww.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!user_id.equals(my_id)){
Intent intent = new Intent(following.this,Friend_profile_view.class);
intent.putExtra("user_id",user_id);
intent.putExtra("image",image);
intent.putExtra("one_word",wins);
intent.putExtra("name",name);
startActivity(intent);
}
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
};
list.setAdapter(firebaseRecyclerAdapter);
}
public static class following_Adapter extends RecyclerView.ViewHolder {
View vieww;
public following_Adapter(View itemView) {
super(itemView);
this.vieww = itemView;
}
public void setImage( final following following, final String image) {
final CircleImageView circleImageView = (CircleImageView)vieww.findViewById(R.id.find_friend_profile_image_card);
if(!image.equals("default_image")) {
Picasso.with(following).load(image).networkPolicy(NetworkPolicy.OFFLINE).into(circleImageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(following).load(image).into(circleImageView);
}
});
}
}
public void setName(String name) {
TextView textView = (TextView)vieww.findViewById(R.id.find_friends_name_card);
textView.setText(name);
}
public void setLine(String line) {
ImageView imageView = (ImageView)vieww.findViewById(R.id.online_or_not);
if(line.equals("offline")){
imageView.setVisibility(View.INVISIBLE);
}
}
public void setOne_word(String wins) {
TextView textView = (TextView)vieww.findViewById(R.id.user_level);
textView.setText(wins);
}
}
Is there any way where i can apply firebase recycler adapter for one node but retrieve data form another node with same key without using addValueEventListener ?
And also most of my app uses firebase recyclerview in all activities so when i observed my android profiler , my RAM usage is increasing while switching between activities i have also used finish(); ended the addValuelistener in onDistroy method but it is still not working.
There are 3 eventListeners that you can use according to your needs, namely valueEventListener, childEventListener and singleValueEventListener.
This will be a good read for this, Firebase Docs.
When working with lists, your application should listen for child events rather than the value events used for single objects.
Child events are triggered in response to specific operations that happen to the children of a node from an operation such as a new child added through the push() method or a child being updated through the updateChildren() method. Each of these together can be useful for listening to changes to a specific node in a database.
In code, childEventListener looks like this:
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
// A new comment has been added, add it to the displayed list
Comment comment = dataSnapshot.getValue(Comment.class);
// ...
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
Comment newComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
// ...
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so remove it.
String commentKey = dataSnapshot.getKey();
// ...
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A comment has changed position, use the key to determine if we are
// displaying this comment and if so move it.
Comment movedComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
// ...
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "postComments:onCancelled", databaseError.toException());
Toast.makeText(mContext, "Failed to load comments.",
Toast.LENGTH_SHORT).show();
}
};
ref.addChildEventListener(childEventListener);
Also, retrieving data without the use of eventListeners is not possible. And if you want to listen to children of your one node, simultaneously, then childEventListener will be a great tool.

Combining Spinner and Button onClick Listener is giving me a Null Pointer exception

I have an app where a person will be allowed to post an announcement. The person has to select on the spinner the category of their announcement and type their announcement on an EditText. After entering both these fields the Button will allow the person to make the Announcement but if the spinner value or the EditText Value is empty an Error should be generated. I tried making the button invisible for the person typing the Announcement because i was getting a Null Pointer Exception but after switching to, making the button invisible I still get the same Error. This is my Code:
public class MakeAnnouncements extends AppCompatActivity {
private EditText announcement;
private Button announce_button;
private ProgressDialog announcementDialog;
private DatabaseReference mRootRef;
private FirebaseAuth mAuth;
private String mCurrentUserId;
private String announcer;
private String []SPINNERCATEGORY ={"General","Cubs","Scouts","Seniors"};
private String category_text;
private MaterialBetterSpinner betterSpinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_make_announcements);
announcementDialog = new ProgressDialog(this);
mRootRef = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
mCurrentUserId = mAuth.getCurrentUser().getUid();
announcement = (EditText)findViewById(R.id.announce_text);
announce_button = (Button)findViewById(R.id.announce_btn);
announce_button.setVisibility(View.VISIBLE);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line,SPINNERCATEGORY);
betterSpinner = (MaterialBetterSpinner)findViewById(R.id.category_spinner);
betterSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
String spinner_value= adapterView.getItemAtPosition(position).toString();
if(position==0){
// no item selected show Toast message
announce_button.setVisibility(View.INVISIBLE);
} else{
announce_button.setVisibility(View.VISIBLE);
// item selected
}
category_text = spinner_value;
return;
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
announce_button.setVisibility(View.INVISIBLE);
}
});
betterSpinner.setAdapter(arrayAdapter);
mRootRef.child("Users").child(mCurrentUserId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
announcer = dataSnapshot.child("name").getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
announce_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) { //<----- This is where i am getting a null point exception
String announced_text = announcement.getText().toString().trim();
String choosen_category = category_text.trim();
if (TextUtils.isEmpty(announced_text)){
announcement.setError("You did not type any announcement");
return;
}
announcementDialog.setTitle("Posting Announcement...");
announcementDialog.setMessage("Please wait...");
announcementDialog.setCanceledOnTouchOutside(false);
announcementDialog.show();
PostAnnouncement(announced_text,choosen_category);
}
});
}
private void PostAnnouncement(String announced_text, String choosen_category) {
DatabaseReference chat_push_key = mRootRef.child("Announcements").child(announcer).push();
String push_key = chat_push_key.getKey();
Map messageMap = new HashMap();
messageMap.put("announcement",announced_text);
messageMap.put("type","text");
messageMap.put("category",choosen_category);
messageMap.put("from",announcer);
messageMap.put("time", ServerValue.TIMESTAMP);
Map messageUserMap = new HashMap();
messageUserMap.put( "Announcements" + "/" + push_key, messageMap);
announcement.setText("");
announcementDialog.hide();
Toast.makeText(getApplicationContext(), "Your announcement was successfully posted",Toast.LENGTH_LONG).show();
mRootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if(databaseError != null){
Log.d("CHAT_LOG", databaseError.getMessage().toString());
}
}
});
}
}
What am i required to do to validate if the spinner Value is not empty?
According to your code you can check on the variable category_text.
if(TextUtils.isEmpty(category_text)){
//Show your error message
}
After checking for possible ways to solve this This Link assisted me.
I first changed the spinner_value to be a global variable. Then wrote this code:
String announced_text = announcement.getText().toString().trim();
String choosen_category = null;
if (TextUtils.isEmpty(announced_text)){
announcement.setError("You did not type any announcement");
return;
}
if(spinner_value != null){
choosen_category = spinner_value.trim();
return;
}
else if(spinner_value == null){
betterspinner.setError("This section must be selected before proceeding");
return;
}
After that i removed button Visibilities that are in my initial code.

Get specific value from Firebase

I have this firebase database:
That has been created with this code:
private DatabaseReference mDatabase;
private EditText tbfirstname;
private EditText tblastname;
private EditText tbemail;
private Button btnSubmit;
private String str_firstname;
private String str_lastname;
private String str_email;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
//GUI DECLARATIONS
tbfirstname = (EditText) findViewById(R.id.tb_firstname);
tblastname = (EditText) findViewById(R.id.tb_lastname);
tbemail = (EditText) findViewById(R.id.tb_email);
btnSubmit = (Button) findViewById(R.id.btn_register);
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//HANDLES VALUES FROM TB TO STR
str_firstname = tbfirstname.getText().toString().trim();
str_lastname = tblastname.getText().toString().trim();
str_email = tbemail.getText().toString().trim();
HashMap<String, String> dataMap = new HashMap<String, String>();
dataMap.put("Firstname", str_firstname);
dataMap.put("Lastname", str_lastname);
dataMap.put("Email", str_email);
mDatabase.push().setValue(dataMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(MainActivity.this,"Registered Successfully!",Toast.LENGTH_LONG).show();
tbfirstname.setText("");
tblastname.setText("");
tbemail.setText("");
} else {
Toast.makeText(MainActivity.this, "There was an Error. Try Again!", Toast.LENGTH_LONG).show();
}
}
});
}
});
}
It's actually a simple app that let users register some data. What I wanna do is I want to create a search textboxthat will locate specific data in the database based on what the user has entered in that textbox and returns a value.
For example I'll search steve#sample.com, if there is an email in the database that has the same value, I want it to return its root value namely L4JyRA77YKldmMWM-C7. If somehow there is no said record, I want it to return with false or something.
Requirements:I'm really a beginner in Android and Firebase so if you could make the code newbie-friendly, that'll really be a great help. Thanks!
first of all you need to fetch all records from firebase database List<User>
create copy of list List<User> temp = new ArrayList();
you can add particular searchable user detail in temp - temp.add(users.get(i));
Now you can get useremail like this email = temp.get(i).getEmailId();
FirebaseDatabase.getInstance().getReference().child("Your table name").orderByChild("email").equalTo(your searchable emailid ).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterator<DataSnapshot> dataSnapshots = dataSnapshot.getChildren().iterator();
List<User> users = new ArrayList<>();
while (dataSnapshots.hasNext()) {
DataSnapshot dataSnapshotChild = dataSnapshots.next();
User user = dataSnapshotChild.getValue(User.class);
users.add(user);
}
String userids = "";
List<User> temp = new ArrayList();
try {
for (int i = 0; i < users.size(); i++) {
if (users.get(i).getEmailid().equals("your searchable email")) {
temp.add(users.get(i));
//Here you can find your searchable user
Log.e("temp", "+" + temp.get(i).getFirebaseId());
email = temp.get(i).getEmailId();
}
}
} catch (Exception e) {
e.printStackTrace();
Log.e("Logs", e.toString());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child("Users").orderByChild("Email").equalTo("editext.getText()");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// dataSnapshot is the "issue" node with all children with id 0
for (DataSnapshot issue : dataSnapshot.getChildren()) {
// do something with the individual "issues"
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Some general things to remember is never name nodes with Capital letters

Increment the value of an Int using a button from a custom listview layout

I have recently managed to make a custom listview layout and populate that data from a listview.
The listview contains a "Like" Button and a textview storing the amount of likes. Yet i cant seem to figure out how to take that int and increment it on button press as the will be performed in the CustomAdapter.
Data Model:
public class MessagesListDataModel {
private String uid;
private String msg;
private String likes;
private String date;
private Button like;
private Button reply;
public MessagesListDataModel(String uid, String msg, String date) {
this.uid = uid;
this.msg = msg;
this.date = date;
this.likes = likes;
}
public MessagesListDataModel(){
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getLikes() {
return likes;
}
public void setLikes(String likes) {
this.likes = likes;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Button getLike() {
return like;
}
public void setLike(Button like) {
this.like = like;
}
}
The Adapter:
public class MessagesListAdapter extends ArrayAdapter<MessagesListDataModel> {
private ArrayList<MessagesListDataModel> dataModels;
public MessagesListAdapter(Context context, ArrayList<MessagesListDataModel> dataModels){
super(context,0, dataModels);
this.dataModels = dataModels;
}
/*
* we are overriding the getView method here - this is what defines how each
* list item will look.
*/
public View getView(int position, View convertView, ViewGroup parent){
MessagesListDataModel messagesListDataModel = dataModels.get(position);
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.chat_messages_layout, parent, false);
}
TextView uid = (TextView) convertView.findViewById(R.id.textViewUserID);
TextView message = (TextView) convertView.findViewById(R.id.textViewMessage);
TextView likes = (TextView) convertView.findViewById(R.id.textViewLikes);
TextView date = (TextView) convertView.findViewById(R.id.textViewDateTime);
Button like = (Button) convertView.findViewById(R.id.buttonLike);
Button reply = (Button) convertView.findViewById(R.id.buttonReply);
uid.setText(messagesListDataModel.getUid());
message.setText(messagesListDataModel.getMsg());
date.setText(messagesListDataModel.getDate());
likes.setText(messagesListDataModel.getLikes());
like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast toast = Toast.makeText(getContext(), "Like button pressed", Toast.LENGTH_SHORT);
toast.show();
//Increment the value of the likes textview and reload that textview to display new likes. Limit the likes to only be able to like a post once.
}
});
reply.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast toast = Toast.makeText(getContext(), "reply button pressed", Toast.LENGTH_SHORT);
toast.show();
//passing data for the reference in the replies class.
}
});
return convertView;
}
}
In the like.SetOnClickListener, how can i retrieve data from firebase database stored as "likes", update the int by adding 1 and store it back into the database?
Can this even be done in the adapter or does this need to take place in the "main activity" of where the data gets populated? Im not sure how to go about this.
Also another problem is that the textviews dont accept Int's so i need to be converting from string to int and back when doing this?
Main Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_room);
//for sending messages to database
btn_send_msg = (Button) findViewById(R.id.btn_send);
input_msg = (EditText) findViewById(R.id.msg_Input);
//Date time
//DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
//dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
//Date date = new Date();
//String dtSent = ((dateFormat.format(date).toString()));
//UserData student ID
FirebaseUser loggedinFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
String userId = loggedinFirebaseUser.getUid();
room_name = getIntent().getExtras().get("room_name").toString();
setTitle(" Room - " + room_name);
//stores the reference as a string to be passed onto the userDataReference table
databaseUrlRef = "users/userData" + "/" + userId;
userDataRef = FirebaseDatabase.getInstance().getReference(databaseUrlRef + "/SID");
chatroomsref = FirebaseDatabase.getInstance().getReference("Chatrooms").child(room_name);
///////
final MessagesListAdapter arrayAdapter = new MessagesListAdapter(this,arrayMessages);
ListViewMessages = (ListView) findViewById(R.id.chatRoomMessagesListview);
ListViewMessages.setAdapter(arrayAdapter);
chatroomsref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//fetchData();
//for (DataSnapshot child : dataSnapshot.getChildren()) {
MessagesListDataModel messagesListDataModel =
dataSnapshot.getValue(MessagesListDataModel.class);
arrayMessages.add(messagesListDataModel);
arrayAdapter.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) {
}
});
/////
//reference to the database that is within the chatrooms and the room name of the name that was clicked and passed onto this activity.
root = FirebaseDatabase.getInstance().getReference("Chatrooms/" + room_name);
userDataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String Name = dataSnapshot.getValue().toString();
user_name = Name;
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//https://stackoverflow.com/questions/40891268/how-to-get-firebase-data-into-a-listview
btn_send_msg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String dtSent = ((dateFormat.format(date).toString()));
Map<String, Object> map = new HashMap<String, Object>();
temp_key = root.push().getKey();
// temp key is the randomly generated key
root.updateChildren(map);
DatabaseReference message_root = root.child(temp_key);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("uid", user_name);
map2.put("msg", input_msg.getText().toString());
map2.put("likes","0");
map2.put("date",dtSent);
message_root.updateChildren(map2);
input_msg.setText("");
}
});
}
}
What im mainly looking for is how could i access this(Chatrooms/RoomName/UNIQUE_ID/likes) as structured in the database, and update it. Where the Unique id is an actual unique id.
FATAL EXCEPTION: main
Process: com.brunelcs.group13.anyquestions, PID: 8808
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
at com.brunelcs.group13.anyquestions.ChatRoom$1.onButtonClick(ChatRoom.java:87)
at com.brunelcs.group13.anyquestions.MessagesListAdapter$1.onClick(MessagesListAdapter.java:81)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24697)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Toast toast = Toast.makeText(getApplicationContext(), getPostKey.toString(), Toast.LENGTH_SHORT);
toast.show();
that i put after getPostKey,
and the other one:
if (btnClickListener != null)
btnClickListener.onButtonClick((Integer) view.getTag());}
Also the arrayAdapter had to be changed to this as it was comming up with errors:
final MessagesListAdapter arrayAdapter = new MessagesListAdapter(this, arrayMessages, new MessagesListAdapter.ButtonClickListener() {}
This is how i am posting the data into firebase:
btn_send_msg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String dtSent = ((dateFormat.format(date).toString()));
Map<String, Object> map = new HashMap<String, Object>();
temp_key = root.push().getKey();
// temp key is the randomly generated key
root.updateChildren(map);
DatabaseReference message_root = root.child(temp_key);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("uid", user_name);
map2.put("msg", input_msg.getText().toString());
map2.put("likes","0");
map2.put("date",dtSent);
message_root.updateChildren(map2);
input_msg.setText("");
}
});
As you can see from answer I posted you in comment you can create an interface inside your Adapter class with one void method and int as parametar for example:
public interface ButtonClickListener {
public abstract void onButtonClick(int position);
}
Then use this in constructor of your adapter class so you can override it inside your Activity and preform ButtonClick. For example:
private ButtonClickListener btnClickListener = null;
public MessagesListAdapter(Context context, ArrayList<MessagesListDataModel> dataModels, ButtonClickListener btnClickListener){
super(context,0, dataModels);
this.dataModels = dataModels;
this.btnClickListener = btnClickListener;
}
After that inside your Adapter class setTag on like button and setOnclickListener on it and get the tag. For example:
likes.setTag(position);
likes.setOnClickListener(new View.OnClickListener{
#Override
public void onClick(View v) {
if(btnClickListener != null)
btnClickListener.onButtonClick((Integer) v.getTag());
}
});
When you are done with this you will be able to implement click listener inside your adapter creation in Activity and then inside using position get the key of post and with that key, retrieve how many likes you have on specific post, make increment and set the value again. Create a new getter and setter inside your model class to store key for example:
private String postKey;
public String getPostKey() {
return postKey;
}
public void setPostKey(String postKey) {
this.postKey = postKey;
}
You will need to store the key inside sePostKey so you can get the key from getPostKey. And then you can easily get it from your MessagesListDataModel:
final MessagesListAdapter arrayAdapter = new MessagesListAdapter(this,arrayMessages, new ButtonClickListener(){
#Override
public void onButtonClick(int position) {
String getPostKey = arrayMessages.get(position).getPostKey();
//Now you have a key to run another query to get data from specific post and with that number of likes as well
}
});
Probably process could be simplified or to use some another better approach but this is just an idea how you could achieve what you want. I didn't test this code I hope it will work.

How to update firebase database values

I have tried too many times but not works this code .How to update specific fields in Firebase database which is mentioned in structure
Here is my structure:
Blog
-LOkCTZQtuMIPT_c9ESK
desc: "wow"
id: "-LOkCTZQtuMIPT_c9ESK"
image:"firebase image"
title:"gh"
uid:"6757576gfgHh6"
So how i can update the desc,image,title these particular fields only with the help of id
Here is my code:
mCurrentUser = mAuth.getCurrentUser();
mDatabase = FirebaseDatabase.getInstance().getReference().child("Blog");
mDatabaseUser = FirebaseDatabase.getInstance().getReference().child("users").child(mCurrentUser.getUid());
private void startPosting() {
mProgress.setMessage("Posting...");
final String title_val = mPostTitle.getText().toString().trim();
final String desc_val = mNameFieldUpdate.getText().toString().trim();
if (!TextUtils.isEmpty(title_val) && !TextUtils.isEmpty(desc_val) && mImageUri != null) {
mProgress.show();
final StorageReference filepath = mStorage.child("Blog_Images").child(mImageUri.getLastPathSegment());
filepath.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
#SuppressWarnings("VisibleForTests")
final Uri downloadUri = taskSnapshot.getDownloadUrl();
final String id = mDatabase.getKey();
mDatabaseUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mDatabase.child(id).child("title").setValue(title_val);
mDatabase.child(id).child("desc").setValue(desc_val);
mDatabase.child(id).child("image").setValue(downloadUri.toString());
mProgress.dismiss();
Intent mainIntent = new Intent(Update_Post.this, Main2Activity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(mainIntent);
finish();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Do this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Blog");
ref.addListenerForSingleValueEvent(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot dataSnapshot){
for(DataSnapshot data: dataSnapshot.getChildren()){
String uid=data.child("uid").getValue().toString();
if(uid.equals((mCurrentUser.getUid()){
String keyid=data.getKey();
ref.child(keyid).child("title").setValue(newtitle);
ref.child(keyid).child("image").setValue(newurl);
ref.child(keyid).child("desc").setValue(newdesc);
}
}
}
Have the location of the listener at child("Blog") and then iterate inside of it and get the key which is keyid. Then to update the values simple point it to the right location and update each one.
You're using getKey() on your base blog DB reference (/Blog). You need to create a new node within that reference with push(), and then getKey() on your newly created child.
final String id = mDatabase.push().getKey();

Categories

Resources