Retrieve and update child data in firebase - java

I have a problem with retrieving and updating a value from Firebase realtime database:
reff = FirebaseDatabase.getInstance().getReference("Items").child(a);
reff.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snap : dataSnapshot.getChildren()) {
Items items = dataSnapshot.getValue(Items.class);
Integer na = items.getItemQuantity();
if (na <= 0) {
Toast.makeText(CheckOut.this, "Out of Stock", Toast.LENGTH_LONG).show();
} else {
na--;
snap.child("itemQuantity").getRef().setValue(na);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Error log on line 60 from the if-else.

According to your last comment:
yes a is the barcode that i will receive from barcode. itemQuantity of a single child.
To get the value of itemQuantity property of a single child, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference barcodeRef = rootRef.child("Items").child("1234567781");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long itemQuantity = dataSnapshot.child("itemQuantity").getValue(Long.class);
Log.d(TAG, String.valueOf(itemQuantity));
//Do what you need to do with itemQuantity
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
barcodeRef.addListenerForSingleValueEvent(valueEventListener);
The result in the logcat will be:
14
The problem in your code is that you are looping through the dataSnapshot object using getChildren() method when is actually not necessary. You should only get the correct reference as in the above code and simply use the value of itemQuantity property as needed.

Related

It does not fetch the required value Firebase Android

It does not fetch the required value and writes null What is wrong with the code please help
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = rootRef.child("analysis_Client").child(searchUserId);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
userTotal = ds.child("Total").getValue(String.class);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
//Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
A picture of the firebase of the way to list the data I want to call both(Total - Rest - ProductNum)

Firebase onDatachange() to set value

Is it possible to set the value using onDataChange() in Firebase? I do not know the value of the post key of each child.
Posts database
databaseReference2 = firebaseDatabase.getReference("Posts");
Query query2 = databaseReference2.orderByChild("userID").equalTo(currentUser.getUid());
query2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull #NotNull DataSnapshot snapshot) {
for(DataSnapshot snap:snapshot.getChildren())
{
Post post = snap.getValue(Post.class);
post.setPicture(image);
post.setUserName(name);
}
}
#Override
public void onCancelled(#NonNull #NotNull DatabaseError error) {
}
});
Is it possible to set the value using onDataChange() in firebase?
Yes, it is.
I do not know the value of the post key of each child.
Actually, there is no need for that.
I just want to update the image and name of each post when users edited their profile name and image.
To achieve that, please use the following lines of code:
databaseReference2 = firebaseDatabase.getReference("Posts");
Query query2 = databaseReference2.orderByChild("userID").equalTo(currentUser.getUid());
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Map<String, Object> update = new HashMap<>();
update.put("picture", image);
update.put("userName", name);
postSnapshot.getRef().updateChildren(update).addOnCompleteListener(/* ... */);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
query2.addListenerForSingleValueEvent(valueEventListener);
You can use getkey() in ondatachange This will give you the keys you are talking to
for(DataSnapshot snap:snapshot.getChildren())
{
String keys = snap.getKey();
}

Get user list from table-1, then compare with data from table-2

I get user list from data-1 table as seen in code below.
DatabaseReference rootReference = FirebaseDatabase.getInstance().getReference();
DatabaseReference reference = rootReference.child("data-1")
ValueEventListener listener= new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final ArrayList<String> userList= new ArrayList<>();
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
String foundUserId= dSnapshot.getKey();
if (condition) {
userList.add(foundUserId);
//step one completed: userList is full with all necessary users
//Now how to iterate it and compare it with data from table-2?
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
reference.addListenerForSingleValueEvent(listener);
}
So far so good, userList has all the users found from data-1 table. But, I still need to filter out some users and add them to second list called filteredUserList. I need to filter them out by comparing each user to the current user that's saved on the final variable currentUserId
I get list of users from data-1, where each user has a list of users under it like so:
data-1
|_____uid1
| |_____uid3: true
| |_____uid4: true
|
|_____uid25
|_____uid34: true
|_____uid101: true
You see in data-1 each user has a list of users under it, which is how I first get to fill userList.
table-2 has timestamp node, and this is its structure:
table-2
|
|____userid1
| |
| |_____timestamp: timestamp
|
|____userid2
|
|_____timestamp: timestamp
//and so on..
What I want to do is, after I have userList filled with users, I need to check whether each user's timestamp is within a certain time delta from the current user. So I need to iterate the userList, and compare each user's timestamp with the current user's timestamp. But I can't get it to work because in order to get each user's timestamp I need a new onDataChange, and in a for loop, but it's out of scope, and it's also async so it's never working! What would be the correct way to make it work? I've been trying for over a week now. Is it even possible to do that?
The simplest solution I can think of is to get current user timestamp and then query the entire users node and compare current user timestamp with the other user timestamps.
I need to filter them out by comparing each user to the current user
So to solve this, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("users")
DatabaseReference uidRef = usersRef.child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long currentUserTimestamp = dataSnapshot.child("timestamp").getValue(Long.class);
String currentUserKey = dataSnapshot.getKey();
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
long timestamp = dataSnapshot.child("timestamp").getValue(Long.class);
if(currentUserKey != ds.getKey()) {
if(currentUserTimestamp > timestamp) {
//Do something
} else {
//Do something else
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
usersRef.addListenerForSingleValueEvent(eventListener);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
Edit: Accoding to the comments and edited question, please see the code below:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference table2Ref = rootRef.child("table-2");
DatabaseReference uidRef = table2Ref.child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long currentUserTimestamp = dataSnapshot.child("timestamp").getValue(Long.class);
String currentUserKey = dataSnapshot.getKey();
DatabaseReference currentUserKeyRef = rootRef.child("data1").child(currentUserKey);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userKey = ds.getKey();
DatabaseReference userKeyRef = table2Ref.child(userKey);
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot d : dataSnapshot.getChildren()) {
long timestamp = d.child("timestamp").getValue(Long.class);
if(currentUserTimestamp > timestamp) {
//Do something
} else {
//Do something else
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
userKeyRef.addListenerForSingleValueEvent(listener);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
currentUserKeyRef.addListenerForSingleValueEvent(eventListener);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);

Retrieve specific value from Firebase database into string variable

I'm trying to retrieve a specific value from a Firebase realtime Database.
The data looks like this:
I want to get the URL value from any of them and then put it into a string variable to use later. This is so that the program does not need to be changed if the download link is changed. The code I have so far is;
DatabaseReference fdb = FirebaseDatabase.getInstance().getReference();
//Query query = fdb.child("URLDOWNLOADS").child("WSSeasons")
fdb.addListenerForSingleValueEvent(new ValueEventListener()
{
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
for (DataSnapshot url : dataSnapshot.getChildren())
{
LoginInfoFirebasedb DownURL = url.getValue(LoginInfoFirebasedb.class);
String temp = DownURL.dwldURL;
URL1 = temp;
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError)
{
}
});
Some help would be seriously appreciated. I understand this may be a simple problem but I am stumped.
To get each url as a String, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = rootRef.child("URLDOWNLOADS");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String key = ds.getKey();
String url = ds.child("URL").getValue(String.class);
Log.d(TAG, key + " / " + url);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
ref.addListenerForSingleValueEvent(valueEventListener);

Multiple Query and Ref Firebase Database Android

My firebase database looks like this:
From this query
String currentUserID = FirebaseAuth
.getInstace()
.getCurrentUser()
.getUid();
DatabaseReference favorsRef = FirebaseDatabase
.getInstance()
.getReference()
.child("favors");
Query myChatsQuery = favorsRef
.orderByChild("uid")
.equalTo(currentUserID);
I need to create other query to get just the tuples from myChatsQuery who has the child called "messages". If the tuple doesn't have the child "messages", I don't want to insert it in my new query.
So, How I can create a query from other query?
Help me please,
Thanks in advance.
Unfortunately, orderByChild() does not work on multiple same fields at once, so you may have to do the job in two steps.
First you can run an orderByChild() query looking for the currentUserId and then add all those that match to an ArrayList and then run orderByChild() in those found uids for messages.
This looks something like this, in code:
reference.orderByChild("uid").equalTo(currentUserId).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists())
array.add(dataSnapshot.getValue(String.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
)};
This code above adds uids matching currentUserId to the ArrayList array.
databaseReference.child(array.get(0)).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.child("messages").exists())
// do your thing
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
)};
You can also just use a for loop to go through all the values in the array.
To solve this, please use the following code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("favors").orderByChild("uid").equalTo(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
if(ds.child("messages").exists()) {
//Do what you need to do
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
query.addListenerForSingleValueEvent(valueEventListener);
As you can see, you can solve this by querying the database only once.

Categories

Resources