Method in button onclick is running even if button is not clicked - android

I am trying to delete or set node values to null in my firebase database, but the the method inside my onClick listener is running without me pressing the button.
btn_cancel.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
DatabaseReference myRef = database.getReference("Orders").child(user_id);
myRef.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
myRef.child("Session").setValue(null);
// myRef.child("Dabba Type").removeValue();
// myRef.child("Start date").removeValue();
// myRef.child("End date").removeValue();
// myRef.child("Address").removeValue();
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
});

If you only want to change/modify data, then setValue() alone is enough. You don't need to attach addValueEventListener. Like this:
public void onClick(View v) {
database.getReference("Orders").child(user_id).child).child("Session").setValue(null);
}
Additional info (maybe will not work if applied to the code in question, but this information likely to be useful)
If you also want to read the value first before committing any change (like confirming if is true then change it to false and otherwise), then you should consider using addListenerForSingleValueEvent instead of addValueEventListener. Because it only do your code once while the later is keep listening to any data change that happen until you remove/detach the listener. And in this case, you should do it like this:
#Override
public void onClick(View v) {
DatabaseReference myRef = database.getReference("Orders").child(user_id);
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue(Boolean.class)) {
// if value is true, change data
myRef.setValue(false);
...
Hope this helps

Related

Android after any changes Firebase Database activity/fragment is closing

i have developed an Android app and I used Firebase for authentication, database and storage. In my app there is navigationview and there are 5 6 fragments. For example there is a profile fragment, users can change personal information in there, but after save button profile fragment is crashing and app is going back to HomePageActivity. There is same problem on uploading images in a activity. Users upload some wound photos, from an activity ,which is reached from a fragment. However after uploading photo to the storage and sending information to database activity is crashing and app is going back to HomePageActivty. I used both addValueEventListener and addListenerForSingleValueEvent, but problem is not been solved. Could you help me?
Here is a example:
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
save();
bringInfo();
Toast.makeText(ProfilActivity.this,"Info changes is saved.",Toast.LENGTH_LONG).show();
}
});
private void save() {
myRef.child("kullanicilar").child(firebaseUser.getUid())
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> postValues = new HashMap<String,Object>();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
postValues.put(snapshot.getKey(),snapshot.getValue());
}
postValues.put("ad", (etNameH.getText().toString()).substring(0,1).toUpperCase()+(etNameH.getText().toString()).substring(1));
postValues.put("soyad", (etSurnameH.getText().toString()).substring(0,1).toUpperCase()+(etSurnameH.getText().toString()).substring(1));
postValues.put("hastane", etCalistigiKurumPr.getText().toString());
myRef.child("kullanicilar").child(firebaseUser.getUid()).updateChildren(postValues);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
}
);
}
private void bringInfo() {
myRef.child("kullanicilar")
.child(firebaseUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
user = dataSnapshot.getValue(Users.class);
etNameH.setText(user.getAd());
etSurnameH.setText(user.getSoyad());
etCalistigiKurumPr.setText(user.getHastane());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
remove calling bringInfo() from btnSave. OnClickListner method and put under onDataChange method try this
public void onClick(View v) {
save();
// bringInfo() remove from here
Toast.makeText(ProfilActivity.this,"Info changes is
saved.",Toast.LENGTH_LONG).show();
}
public void onDataChange(DataSnapshot dataSnapshot) {
// *****Remaining Code*****
bringInfo() put it here
}

How to display data automatically without having to use a button?

Currently, to get the data from the firebase database, I use button to get the data and display them into textview. However, every time i uploaded data, i need to click the button in order to get the data to be displayed.
Therefore, is there a way to display the data right away after the upload session instead of clicking the button to display them?
Below code shows how i display the data at the moment by clicking button which works successfully.
Thanks!
fetch=(Button) v.findViewById(R.id.bFetch_Schedule);
fetch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dayRef.child("Subject").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
textViewSubject_Schedule.setText(value);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
dayRef.child("What is in our class?").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
textViewWhat_Schedule.setText(value);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
You need to use addValueEventListener() instead of addListenerForSingleValueEvent().
The listener you provided to addValueEventListener() is called each time the data changes.
The listener you provided to addListenerForSingleValueEvent() is called once with the value of the data at the location.
You may also want to check addChildEventListener(). All information available at the related doc.
You are using addListenerForSingleValueEvent, which gets the value from Firebase and then stops listening. If you use the same code with addValueEventListener it will keep receiving updates.
dayRef.child("Subject").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
textViewSubject_Schedule.setText(value);
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
You'd typically put this code in a lifecycle event of the activity, such as onCreate or onStart.

How to update user data Firebase?

I want to increment score by 1 when user clicks a button, but value of score is not updated. When I updated it manually from Firebase console it updates. I don't know what the problem is. Can anyone help me, please?
#Override
public void onClick(View view) {
if (view == add) {
score++;
databaseReference1 = databaseReference.child("score");
databaseReference1.setValue(String.valueOf(score));
databaseReference1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
textView_earning.setText(score + " ");
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
You have to add the value event listener before changing the value.
#Override
public void onClick(View view) {
if (view == add) {
score++;
ref1 = ref.child("score");
ref1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
textView_earning.setText(score + " ");
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
ref1.setValue(String.valueOf(score));
}
}
If you place addValueEventListener inside onClick(), you'll end up attaching one more listener into databaseReference1 every time the button clicked. It is not a best practice as you'll face more kind of problem if it is clicked multiple time.
You should place addValueEventListener somewhere else, like (not limited to) in activity's onCreate() method:
... onCreate(...) {
databaseReference1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
And place score variable where it is easily got, and update it inside onDataChange() (for this example, I place it on scoreValue:
private String scoreValue;
... onCreate(...) {
databaseReference1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
scoreValue = dataSnapshot.getValue(String.class)
}
...
And then inside onClick(), you just need to get scoreValue, increment it by 1, and save the value:
... onClick() {
if (view == add) {
scoreValue++;
databaseReference.child("score").setValue(scoreValue);
}
}
Then setValue(scoreValue) will update the value at the online database, and trigger onDataChange(). So don't worry if the value is changed online, scoreValue will always have updated value.
Hope this helps.
Note: all of this consider score value is at (your databaseReference
path)\score
you can use updateChildren for update single values.
Firebase ref = new Firebase(Constants.FIREBASE_URL);
HashMap<String, Object> hm = new HashMap<String, Object>();
hm.put("score", score++);
ref.child("YOUR_ROOT_NODE")
.updateChildren(hm);
thanks all for your answer,the problem is fixed,actually i make a stupid mistake as i do not set on click listener on my button

how do i retrieve data from firebase without listening for changes?

I wanted to create an application that uses firebase as a backend.Now the problem I have is that I have to attach a listener to get back a snapshot of data. But for every time my application starts,I want to query firebase for data and populate my views even though there has been no change in the database.
I suppose you are doing something like this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Code
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Code
}
});
So for what I think you're asking, calling an alternative method called addListenerForSingleValueEvent should solve the problem. It will not listen for changes, as soon as returns a value, it will stop connecting until being attached again.
Result
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Code
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Code
}
});

Can i get value without using event listeners in firebase on android?

I'm making an Android application using new version of Google Firebase Realtime Database.
I am getting my datas with ValueEventListener and ChildEventListener when data changed/added/deleted/moved etc..
Now, i have a problem.
My data is :
"user 1": {
"name":"abc"
}
and i have an a Button that named "getName".
I want to get value of "name" in user 1 data when i clicked the getName button.
getName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bla bla..
}
});
Is it possible?
Can i get value without using listeners?
i m waiting your helps.
thank you.
Yes you can do that by using addListenerForSingleValueEvent. This will fetch the value only once unlike ValueEventListener and ChildEventListener.
So your code will look something like this,
getName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
// do some stuff once
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Not actually true it will change every time you change the data and it will probably call all of your activites which is pretty useless i don't even know why they made it that way....waiste of time.
Take a look at Tasks API framework:
#Override
public void onClick(View view) {
getUser();
}
private Task<User> getUser(String id) {
final TaskCompletionSource<User> tcs = new TaskCompletionSource();
ref.child("users")
.child(id)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onCancelled(FirebaseError error) {
tcs.setException(error.toException());
}
#Override
public void onDataChange(DataSnapshot snapshot) {
tcs.setResult(snapshot.getValue(User.class));
}
});
return tcs.getTask();
}
Of course, there is a way to achieve this, maybe not the way you want it. The first thing you have to do is to create a Model class for the 'user', let's call it User, it might go something like this:
package Model;
public class User{
private String name; // make sure this matches the one in Firebase
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
public User()
{
//this non-argument constructor is necessary for Firebase to properly map all the variables.
}
public User(String name) {
this.name= name;
}
}
Now in a different activity, where you want to access the user's name.
getName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
databaseRef.child("users").child("user1").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
User user = snapshot.getValue(User.class);
Log.i("user name", user.getName());
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
If your reference points to the 'users' node and you want to find a user with a specific name and access its other attributes, you can do this.
getName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
databaseRef.child("users").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
User user = snapshot.getValue(User.class);
if(user.getName().equals("abc"))
{
Log.i("other data", user.getOtherData());
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});

Categories

Resources