Run as a transaction in Realtime Database [duplicate] - android

This question already has answers here:
How to save users score in firebase and retrieve it in real-time in Android studio
(3 answers)
Closed 2 years ago.
I am trying to make an application on Android, I am a beginner.
I try to increment the "stock" of a product, but my following code is not reliable. I had connection problems on the device and the "stock" did not increase correctly. How can I execute it as a transaction?. I cannot find extensive documentation.
final HashMap<String, BigDecimal> detalle = new HashMap<String, BigDecimal>();
Query query = mDatabase.child("COMPRAS").child(key).child("COMPRASPRODUCTO");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
CompraProducto producto = ds.getValue(CompraProducto.class);
detalle.put(producto.getId(),new BigDecimal(producto.getCantidad()));
}
for (String key : detalle.keySet()) {
Query queryp = mDatabase.child("PRODUCTO").child(key);
queryp.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot data) {
Producto p = data.getValue(Producto.class);
try{
stockOriginal = new BigDecimal(p.getStock());
mProductoProvider = new productoProvider();
mProductoProvider.refreshStock(p.getCodigo(), stockOriginal.add(detalle.get(p.getCodigo())).toString()).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
}
});
}catch(Exception e){
Toast.makeText(comprarProducto.this, "Producto " + data.getKey() + " no existe.", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
Thank you.

I am using updateChildren and ServerValue.increment
Using these paths, you can perform simultaneous updates to multiple locations in the JSON tree with a single call to updateChildren(), such as how this example creates the new post in both locations. Simultaneous updates made this way are atomic: either all updates succeed or all updates fail.
final Map<String, Object> productUpdates = new HashMap<>();
Query query = mDatabase.child("COMPRAS").child(key).child("COMPRASPRODUCTO");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
System.out.println("---" + ds.getKey());
CompraProducto producto = ds.getValue(CompraProducto.class);
productUpdates.put("/PRODUCTO/" + ds.getKey() +"/stock", ServerValue.increment(producto.getCantidad()));
}
System.out.println("==============");
if(!productUpdates.isEmpty()) {
mDatabase.updateChildren(productUpdates, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError == null) {
mCompraProvider.actualizar(key, inputProveedor.getText().toString(), inputFecha.getText().toString(), "PENDIENTE").addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(comprarProducto.this, "Compra del proveedor " + inputProveedor.getText().toString() + " guardada correctamente.", Toast.LENGTH_SHORT).show();
}
});
System.out.println("onComplete: success");
} else {
System.out.println("onComplete: fail" + databaseError.toException());
}
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});

Related

No result getting from firebase database

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) {
}
});
}
}

How to read data from RecyclerView and make comparison?

Hi I want to read the display data from RecyclerView and make comparison.
This my layout for the activity:
What I want to do is to read all data from RecyclerView and compare with Daily Calorie Suggestion.
After reading all data, I need to make comparisons on how many times the user have taken above, less or sufficient total calories as shown in the "Analysis of Total Calories Consumed of Last 7 Days"
The code:
#Override
protected void onStart() {
Query query = ref.orderByChild("timeStamp").limitToLast(7).endAt(Date);
super.onStart();
if (query != null) {
query .addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userHighlights = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
userHighlights.add(ds.getValue(HighightsModel.class));
requiredCalorieRef = FirebaseDatabase.getInstance().getReference("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
requiredCalorieRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String userCalorieSuggestion = String.valueOf((dataSnapshot.child("daily calorie").getValue()));
int daily_calorie = Integer.parseInt(userCalorieSuggestion);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
HighlightsAdapter highlightsAdapter = new HighlightsAdapter(userHighlights);
highlightsRV.setAdapter(highlightsAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(UserNewHighlights.this, databaseError.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
}
}
This is my firebase:
Do I have to write a new code to solve this problem or else? Any help will be much appreciated. Thanks
As #MasoudDarzi mentioned, it's not related to the RecyclerView.
You can try something like this:
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userHighlights = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
userHighlights.add(ds.getValue(HighightsModel.class));
requiredCalorieRef = FirebaseDatabase.getInstance().getReference("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
requiredCalorieRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String userCalorieSuggestion = String.valueOf((dataSnapshot.child("daily calorie").getValue()));
int daily_calorie = Integer.parseInt(userCalorieSuggestion);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
HighlightsAdapter highlightsAdapter = new HighlightsAdapter(userHighlights);
highlightsRV.setAdapter(highlightsAdapter);
// do calculation here with userHighlights
int countExceeded = 0, countBelow = 0, countSufficient = 0;
for (HighightsModel h : userHighlights) {
if (h.totalCalorie > daily_calorie) {
countExceeded++;
} else if (h.totalCalorie < daily_calorie) {
countBelow++;
} else {
countSufficient++;
}
}
// update your TextView with the count numbers
// todo
}
}
so The brute force solution is to have a for in your data after getting the 7 days average.
for (your 7 days data){
// check if your data is lower or higher than the average
// and store number of higher or lower
}
looking for a better solution?
I have solved my problem by adding another child at History node. Whereby, previously I have only these for History :
but I add new child which is called STATUS, the status is updated from previous activity as seen the pic below:
so what I did for the code is :
private void upDateAnalysisAbove() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("History");
DatabaseReference mRef = ref.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
Query mQuery = mRef.orderByChild("status").equalTo("ABOVE").limitToLast(7);
mQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = String.valueOf(dataSnapshot.getChildrenCount());
int values = Integer.parseInt(value);
txt_above_output.setText(values + " times(s)");
upDateAnalysisLess(values);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
//LESS
private void upDateAnalysisLess(int values) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("History");
DatabaseReference mRef = ref.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
Query mQuery = mRef.orderByChild("status").equalTo("LESS").limitToFirst(7);
mQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String valueLess = String.valueOf(dataSnapshot.getChildrenCount());
int values_Less = Integer.parseInt(valueLess);
if (values_Less == 0){
txt_less_output.setText(values_Less + " times(s)");
}
if (values > values_Less){
int finalCount = values - values_Less ;
txt_less_output.setText(finalCount + " times(s)");
}
if (values <values_Less){
int finalCount = values_Less - values ;
txt_less_output.setText(finalCount + " times(s)");
}
updateSuff();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
//SUFFICIENT
private void updateSuff() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("History");
DatabaseReference mRef = ref.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
Query mQuery = mRef.orderByChild("status").equalTo("SUFFICIENT").limitToFirst(7);
mQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = String.valueOf(dataSnapshot.getChildrenCount());
int suffValue = Integer.parseInt(value);
if (suffValue == 0) {
txt_sufficient_output.setText(suffValue + " times(s)");
}
if (suffValue != 0){
txt_sufficient_output.setText(suffValue + " times(s)");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Here is the output:
credit to this post that helped me a lot, and thanks for those who tried to help me.

android-Firebase RealTime Database orderByChild not working [duplicate]

This question already has an answer here:
Order by date in negative timestamp is not working in Firebase
(1 answer)
Closed 4 years ago.
I am doing everything as per documentation but don't know why I am not getting ordered data
My Query
typeRef = myRef.child("DiscussionRooms").orderByChild("order");
valueEventListener = typeRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
Log.d(TAG, "Get Data" + dataSnapshot.getValue().toString());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
My Database
My Database Rules
Response Logs
To display the data ordered according to the order property, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference discussionRoomsRef = rootRef.child("DiscussionRooms");
Query orderQuery = discussionRoomsRef.orderByChild("order");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
Log.d("TAG", name);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
};
orderQuery.addListenerForSingleValueEvent(valueEventListener);

Firebase get a value under unknown push key

How can I get that value while I know nothing about the push key?
+users
+9JZTuGUzc8bx7FLrwResWmp8L583
+anon:
+email:
+fid: <- i want to get this id without knowing push key (9JZTuGUzc8bx7FLrwResWmp8L583 )
+username:
Currently, I am trying with a null response:
FirebaseDatabase.getInstance().getReference().child("users").orderByChild("anon").equalTo(getIntent().getStringExtra(EXTRA_POST_USERNAME))
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user information
if(dataSnapshot.exists()){
User user = dataSnapshot.getValue(User.class);
fidanon = user.fid;}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
final Query query = FirebaseDatabase.getInstance().getReference().child("users").orderByChild("anon").equalTo(getIntent().getStringExtra(EXTRA_POST_USERNAME));
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot != null) {
final String fid = dataSnapshot.child("fid").getValue().toString();
Toast.makeText(getActivity(), fid, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Use this,will solve your problem.

How to check if firebase query is empty

I want to delete the data from Firebase before unauthorizing. The problem is that mFirebaseRef.unauth() works only if query is not empty. But I need it to work even if query is empty.
final Firebase pushNotificationRef = new Firebase(Constant.FIREBASE_URL_PUSHNOTIFICATIONS);
final Query queryRef = pushNotificationRef.orderByChild("deviceToken").equalTo(token);
queryRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.exists()) {
Log.e("MyTag", dataSnapshot.getKey());
pushNotificationRef.child(dataSnapshot.getKey()).removeValue();
}
mFirebaseRef.unauth();
}
use this...
if (dataSnapshot.exists())
// user found
else
// user not found
demo example
Query query = dbstud.child("users").orderByChild("name").equalTo("XYZ");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Toast.makeText(getApplicationContext(), "id = " + snapshot.getKey(), Toast.LENGTH_LONG).show();
}
}
else {
Toast.makeText(getApplicationContext(), "User Not found ", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});

Categories

Resources