So... thanks to some great assistance from TomiQsrd I have got my data being saved in Firebase as below:
private void saveUserInformation(){
String name = editTextName.getText().toString().trim();
String address = editTextAddress.getText().toString().trim();
FirebaseUser user = firebaseAuth.getCurrentUser();
databaseReference.child(user.getUid()).child("Name").setValue(name);
databaseReference.child(user.getUid()).child("Address").setValue(address);
Toast.makeText(this, "Information Saved...", Toast.LENGTH_SHORT).show();
}
The rest of my project is pretty much completed, but I have one last part I can't figure out no matter how many tutorials I watch/read.
How on earth do I get an event listener to pick up changes in the data and update a TextView field.
eg. As a test, I want to add a textViewName field to the page to update when the name is updated in editTextName
I have tried all sorts of approaches and must have been close, but I have not been able to get it to work.
See https://firebase.google.com/docs/database/android/read-and-write
Modified from there:
databaseReference.child(user.getUid()).child("Name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
String name = snapshot.getValue(String.class);
myTextView.setText(name);
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// ...
}
};
Related
I have an activity that registers active time data to my Firebase Realtime Database, this is input manually using an EditText which then displays it to a TextView in the UI. This is all working fine, however, if I was to put more data in, it would simply replace the value in the database and TextView.
I have previously done something similar to this in another activity (Adding (Sum) multiple Firebase child values together to give a total value?), however, this activity had additional nodes with dates, etc so the same approach would not work in my current activity. Ideally, I would have this node organized with dateStrings etc, however, for demonstration purposes, it's not necessary. Therefore I would just like to take whatever value is already existing in the database and add to it the input value, then restore that to the database.
It's probably quite simple but I've been staring at it so long I've confused myself. This is nowhere near right but just a bit confused about my next steps.. I've seen perhaps something along these lines how to sum money value in firebase realtime android studio but wondering if this is the easiest way?
Register Activity method:
registerActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String activityTime = activeMinutes.getText().toString().trim();
databaseReference.child("active time").setValue(activityTime);
addActivity.setVisibility(View.VISIBLE);
registerActivity.setVisibility(View.GONE);
activeTimeTI.setVisibility(View.GONE);
}
});
Method to display data (shortened):
databaseReference.addValueEventListener(new ValueEventListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int total = 0;
String activityTime = dataSnapshot.child("active time").getValue(String.class);
if (activityTime == null) {
activeTimeTV.setText("0");
} else {
total += Integer.parseInt(activityTime);
activeTimeTV.setText(String.valueOf(total) + " minutes");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG", "onCancelled", databaseError.toException());
}
});
Firebase Hierarchy:
According to your last comment:
Active Time is at 500 (mins) just now, if I did another 90 mins of activity, I would like to add 90 to that value and then update that to show 590.
To increment the value of "active time" by 90, first of all, you need the change the type of the field to be number. That being said, your field should look like this:
ndkdn
|
--- active time: 500
See, there are no quotation marks. If your "ndkdn" node is a direct child of your Firebase Realtime Database root, to increase the value by 90, simply use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference activeTimeRef = rootRef.child("ndkdn").child("active time");
activeTimeRef.setValue(ServerValue.increment(90));
This kind of operation is atomic. If you are not allowed to change the type of your field, to also have consistent data, then you should read the value first and increment it right after that using a transaction:
activeTimeRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer activeTime = Integer.parseInt(mutableData.getValue(String.class));
if (score == null) {
return Transaction.success(mutableData);
}
mutableData.setValue((activeTime + 90) + "");
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError error, boolean b, DataSnapshot snapshot) {
Log.d("TAG", error.getMessage()); //Don't ignore potential errors!
}
});
I am learning how realtime databases work, so be patient.
To better explain my doubt, I take an image showing the relevant part of the realtime database
https://prnt.sc/p0wmvs
All I want is the best way to update the field "name" of a record "grps".
The starting point is the "usrs" table where I can reference
mFD.getReference("usrs/"+user.getUid()+"/asAdm/grps/"+grpId)
My function to update "name" of group name
public void editGroupFromUser(long grpID, Group group, final DataStatus dataStatus) {
DatabaseReference mFRUser = mFirebaseDatabase.getReference(
"usrs/"+user.getUid()+"/asAdm/gprs/"+grpID
);
mFRUser.child("grp").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String groupKey = (String) dataSnapshot.getValue();
DatabaseReference mFRGroup = mFirebaseDatabase.getReference("grps");
mFRGroup.child( groupKey ).setValue(group).addOnSuccessListener(aVoid -> {
dataStatus.DataIsUpdated();
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
The need to receive the group key to then send the group update. This does not seem efficient at all.
Also, the need to send the user Uid key when the user is identified in firebase does not seem safe at all.
Is there any better way to do this?
I am attempting to delete a value from a node in Firebase.
It seems that the onDataChange is not being reached.
I tried looking up the docs and articles and used some of the code that I saw referenced in multiple places(e.g. Remove Specific value From Firebase Database). Log statements inside onDataChange are not being called but the Log statements before it are. The scope of email is fine as can be seen by the log statement
I/emailRemove: 111#aol.com
I/removeEmail: Inside Method
In this example I would like to delete whatever area has the email "111#aol.com" :
private void removeEmail() {
Log.i("emailRemove", email);
Log.i("removeEmail","Inside Method");
Query emailQuery = mDatabase.child("emailAddress").equalTo(email);
emailQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot emailSnapshot: dataSnapshot.getChildren()) {
Log.i("snapshot", emailSnapshot.toString());
Log.i("snapshotRef", emailSnapshot.getRef().toString());
emailSnapshot.getRef().removeValue();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("TAG", "onCancelled", databaseError.toException());
}
});
}
Since you want to filter by a child property, you should use orderByChild(...):
Query emailQuery = mDatabase.orderByChild("emailAddress").equalTo(email);
emailQuery.addListenerForSingleValueEvent(new ValueEventListener()
You'll also want to make sure you run this query against RC9..., since that is the only node where the child nodes have an emailAddress property.
Good day, I am using Android studio to create a question and answer based game and I have a 2 things that I am struggling with. I have a firebase database with the following structure:
database name{
answers{
1{
answer_option_1: .....
answer_option_2: .....
answer_option_3: .....
answer_option_4: .....
}
2{
answer_option_1: .....
answer_option_2: .....
}
and so it carries on similar to the above shown structure.
My question is regarding how I could retrieve the answer options and store them in their respective variables? such as:
Option1 = answer_option_1
Is there a way to count the number of children under the parent, such as, it should tell me that under the parent 2, there are 2 children?
My code for retrieving a single value is as follows:
mDatabase.child("answers").child(num).child("answer_option_1").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Option1 = dataSnapshot.getValue().toString();
option1.setText(Option1);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
where mDatabase is the reference to my Firebase Database and num is a random value to retrieve a random question . I have repeated the above code a 4 times for the 4 options, but when I have 2 options, as mentioned and shown in the database structure above, my app stops working.
All help will be highly appreciated.
I'm still not getting why do you want to count the children but you might be interested in using ChildEventListener to get a callback for each child inside /answers/num.
Set a list that will track the options:
List<String> options = new ArrayList<>();
And when loading the view or whatever make sure you start the listener:
mDatabase.child("answers").child(num).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot) {
String option = dataSnapshot.getValue().toString();
options.add(option);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
System.out.println(ref.child("mostafa_farahat22#yahoo.com").child("_email"));
*i`m trying to get a value of child but all time i get the URL of the value
how to get the value of this URL as i try by this code but it get me the URLi want to get the _email value.
You are looking at the concept from the wrong angle.
While using the ref.child("mostafa_farahat22#yahoo.com").child("_email") you are just simply pointing at a particular place in your database and nothing more.
If you want to retrieve the data in that particular place, consider these 2 ways.
First if you want to retrieve the data only once, you can do the following :
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
DatabaseReference mostafa = ref.child("Users").child("mostafa_farahat22#yahoo.com").child("_email");
mostafa.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String email = dataSnapshot.getValue(String.class);
//do what you want with the email
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
or maybe you want to retrieve the value in real time and use it in the same time that the database value is changed, all in the same time, whenever the value in changed, then you use this :
mostafa.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String email = dataSnapshot.getValue(String.class);
display.setText(email);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Note the difference between the two methods. First is only for one time retrieve and the second is for retrieving the data whenever the value is changed.
Just have in mind that the codes that i posted are just templates and may need to play with them a bit.
With ref.child("mostafa_farahat22#yahoo.com").child("_email") you are just setting the reference to the object. Take a look at the java firebase documentation to retrieve data.
To get the data you will need to set a listener for your reference
ref.child("mostafa_farahat22#yahoo.com").child("_email").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
// data available in snapshot.value()
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});