I would to update an existing value in my Firebase Realtime Database. I have tried several ways but none have worked. Anyone know how can I fix it? I attach the structure of the db if it can be useful and the code I have written so far. Thanks in advance to everyone
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference().child("users");
myRef.orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.getValue() != null) {
//loop through the keys
Map<String, Object> hashMap = new HashMap<>();
for(DataSnapshot datasnap : snapshot.getChildren()) {
if(datasnap.child("email").getValue().toString().equals(email)) {
hashMap.put("address", "TEST1");
myRef.child(email).updateChildren(hashMap).addOnSuccessListener(new OnSuccessListener() {
#Override
public void onSuccess(Object o) {
Toast.makeText(LocationActivity.this, "Data successfully update",
Toast.LENGTH_SHORT).show();
}
});
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
You're updating the wrong location in the database, which means that either the write is now showing up in the screenshot or it is rejected (which your code doesn't handle).
To update the address of the child node you're looping over:
myRef.orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot datasnap : snapshot.getChildren()) {
datasnap.child("address").getRef().setValue("TEST1").addOnSuccessListener(new OnSuccessListener() {
#Override
public void onSuccess(Object o) {
Toast.makeText(LocationActivity.this, "Data successfully update",
Toast.LENGTH_SHORT).show();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
The key change here is that I call getRef() on the snapshot, to get a reference to that specific location in the database.
You'll note that I also removed the two conditions, since neither of them had any effect on the outcome.
FirebaseFirestore ff = FirebaseFirestore.getInstance();
ff.collection("myCollection")
.document(myAuth.getCurrentUser().getUid())
.update("field",value)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
//for example Toast.makeText(context,getString(R.string.user_updated),Toast.LENGTH_SHORT).show();
}
}
});
Related
I just started to learn Android Studio, and I am trying to make a search activity that can search for a data from my firebase database. But whenever I try to search no result shows up on the screen and does not retrieve any data from the database. Can anyone solve the problem? Thanks.
private void searchForMatch(final String keyword) {
Log.d(TAG, "searchForMatch: searching for a match: " + keyword);
imageDTOs.clear();
if(keyword.length() == 0) {
} else {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child("books").orderByChild("title").equalTo(keyword);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
Log.d(TAG, "onDataChange: found book:" + singleSnapshot.getValue(ImageDTO.class).toString());
imageDTOs.add(singleSnapshot.getValue(ImageDTO.class));
}
searchAdapter = new SearchAdapter(SearchActivity.this, R.layout.item_library, imageDTOs);
listView.setAdapter(searchAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
I have the data in firebase as given below:
I want to get the Customer and Device details for each of the Form ID. The Form IDs are generated uniquely by firebase.
I just somehow need to get access to these Form IDs.
I have set the databaseReference as follows:
databaseReference = FirebaseDatabase.getInstance().getReference("users").child(userID).child("forms");
Then I have tried the following code to retrieve the required data:
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot formsSnapshot : dataSnapshot.getChildren()) {
for (DataSnapshot formIDSnapshot : formsSnapshot.getChildren()) {
Device device = formIDSnapshot.getValue(Device.class);
if (device != null) {
// get and use the data
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Update:
I am now successfully able to retrieve the form IDs, thanks to the answer by #Frank.
Now, to get the Device and Customer details I have to write the following code inside the ValueEventListener after getting the form IDs:
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot formsSnapshot : dataSnapshot.getChildren()) {
String formID = formsSnapshot.getKey(); //Retrieving the formID here
//New code addition
// to get the reference to device details node
databaseReference.child(Objects.requireNonNull(formID)).child("Device details").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Device device = dataSnapshot.getValue(Device.class);
if (device != null) {
// required device details here
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
// to get the reference to customer details node
databaseReference.child(Objects.requireNonNull(formID)).child("Customer details").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Customer customer = dataSnapshot.getValue(Customer.class);
if (customer != null) {
//required customer details here
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
I understand that this is a messy code and I would like to get some cleaner approach for the same.
You can get the key of a node by calling DataSnapshot.getKey(). So to get your form IDs:
databaseReference = FirebaseDatabase.getInstance().getReference("users").child(userID).child("forms");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot formsSnapshot : dataSnapshot.getChildren()) {
String formID = formsSnapshot.getKey();
Device device = formsSnapshot.getValue(Device.class);
if (device != null) {
// get and use the data
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
There is no need for the nested loops. Simply get the children list and loop over it once. At every iteration, cast dataSnapshot to FormID class and afterwards just use its properties.
i would also suggest that you use SingleValueEventListener instead of ValueEventListener if you do not need to observe the data all the time
I want to retrieve houfxWvbwyVmbHX60IGjpNkZR9w2 key , How to do?
Here is the code for the same
mQuery = mfollowing.orderByChild("following").equalTo(user_id);
mQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final String key = dataSnapshot.getKey();
mdatabaseUsers.child(user_id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DatabaseReference newfollscreen = mdatabaseFollwer.child(key).child(newPost.getKey());
newfollscreen.child("screen").setValue(downloadUrl.toString());
newfollscreen.child("engagement").setValue("NA");
newfollscreen.child("url").setValue("NA");
newfollscreen.child("uid").setValue(user_id);
newfollscreen.child("name").setValue(dataSnapshot.child("name").getValue());
newfollscreen.child("image").setValue(dataSnapshot.child("image").getValue()).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(AddimageActivity.this, "Posted among your followers", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(AddimageActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled (DatabaseError
databaseError){
}
});
Here is the Firebase database
second image
enter image description here
I tried using child data snapshot method but did not worked. Any help for this will be much appreciated.
Assuming you have a DataSnapshot that points to the children rhZ4...wt2, you can call snapsthot.getRef().toString() which will return you something like https://xxx.firebaseio.com/.../houfxWvbwyVmbHX60IGjpNkZR9w2/rhZ4...wt2. From there you can extract the parent key.
From your example, after you query the database using mQuery, inside onDataChange you have a DataSnapshot.
So calling dataSnapshot.getRef().toString() will give you https://xxx.firebaseio.com/.../houfxWvbwyVmbHX60IGjpNkZR9w2/rhZ4...wt2/following.
Code to extract the parent key (put it inside your 1st onDataChange):
String reference = dataSnapshot.getRef().toString();
String[] tokens = reference.split("/");
String parentKey = tokens[tokens.length - 3];
This parentKey should be your houfxWvbwyVmbHX60IGjpNkZR9w2.
I want to get list of all Allowed child from this type of JSON Tree:
databaseRef.child('Users').child('Allowded').addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange (DataSnapshot dataSnapshot) {
//
}
}
#Override
public void onCancelled (DatabaseError databaseError) {
} };);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference userRef = database.getReference("users").child(key).child("Alloweded");
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User userObj = dataSnapshot.getValue(User.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// ...
}
};userRef.addValueEventListener(postListener);
User is your Model class which have lat, lng, name,no., profileUrl etc
Try this I hope it works fine.
Firebase listeners fire for both the initial data and any changes.
If you're looking to synchronize the data in a collection, use ChildEventListener. If you're looking to synchronize a single object, use ValueEventListener. Note that in both cases you're not "getting" the data. You're synchronizing it, which means that the callback may be invoked multiple times: for the initial data and whenever the data gets updated.
FirebaseRef.child("message").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println(snapshot.getValue()); //prints "Do you have data? You'll
love Firebase."
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
databaseRef.child('Users').child('Allowded').addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange (DataSnapshot dataSnapshot) {
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
Log.d(TAG, "onDataChange: 1 " + childDataSnapshot.getKey());
for (DataSnapshot childDataSnapshot2 : childDataSnapshot.getChildren()){
Log.d(TAG, "onDataChange: 2 " + childDataSnapshot2.getKey());
}
}
}
}
#Override
public void onCancelled (DatabaseError databaseError) {
} };);
How can I get the
"Dancing in the dark"
from this snapshot if the snapshot does not exist:? I figure it must be saved in the snapshot somewhere. Please read inline code comments..
private void addListenerForSingleValueEvent(String streetAddress, StringBuilder targetAddress){
DatabaseReference firebase = FirebaseDatabase.getInstance().getReference();
firebase.child("catalog/trax").orderByChild("namn").equalTo("Dancing in the dark")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
// do sowm work on existing data
} else {
// How can I get the "Dancing in the dark" from the snapshot?
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(Application.getInstance(), databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result. By listening to a value event you get all matching results in one snapshot, so you have to iterate over the children.
DatabaseReference firebase = FirebaseDatabase.getInstance().getReference();
firebase.child("catalog/trax").orderByChild("namn").equalTo("Dancing in the dark")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot item: snapshot.getChildren()) {
// In this loop item is the snapshot of a single item.
// This means we can get the namm of the item
System.out.println(item.child("namm").getValue(String.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(Application.getInstance(), databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});