The user is prompted to convert the earned coins into experience, but I want to use a FireBase entry to verify the user. It is necessary that the user leaves a request for convert. When writing to FireBase, the user specifies the number of coins to be converted. And accordingly, he needs to write them off the balance sheet. The minimum amount to convert is 5000 coins.
Here is the code I am trying to write data to FireBase:
public void onClickResetCoin(View view) {
mDatabase = FirebaseDatabase.getInstance().getReference("Resets");
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
users.child(userID).child("coins").setValue(rescoin);
int coins = Integer.parseInt(edCoins.getText().toString());
int ResetCoin = rescoin - coins;
String resetcoin = String.valueOf(ResetCoin);
Reset newReset = new Reset(resetcoin);
mDataBase.push().setValue(newReset);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Based on the code you have provided, it seems that you are trying to update the user's coin balance and create a new entry in the "Resets" node to track the user's reset history. However, it is not clear how this code is related to your goal of allowing the user to convert earned coins into experience.
To implement the feature of converting coins into experience, you could follow these steps:
Create a new node in your Firebase database to store conversion requests. For example, you could create a "ConversionRequests" node with the following structure:
ConversionRequests
- Request1
- userId: "user1"
- coinsToConvert: 5000
- Request2
- userId: "user2"
- coinsToConvert: 10000
Modify your app's UI to allow the user to submit a conversion request. You could add a button or a form where the user can enter the number of coins they want to convert and submit the request.
When the user submits a conversion request, write the request data to the "ConversionRequests" node in Firebase using the setValue() method. You can use the FirebaseAuth class to get the currently signed-in user's ID, and then create a new child node under "ConversionRequests" with the request data.
Here's an example code snippet that demonstrates how to write a conversion request to Firebase:
FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
String userId = currentUser.getUid();
int coinsToConvert = Integer.parseInt(edCoins.getText().toString());
if (coinsToConvert < 5000) {
// Handle error: minimum conversion amount is 5000 coins
return;
}
DatabaseReference conversionRequestsRef = FirebaseDatabase.getInstance().getReference("ConversionRequests");
String requestId = conversionRequestsRef.push().getKey();
ConversionRequest request = new ConversionRequest(userId, coinsToConvert);
conversionRequestsRef.child(requestId).setValue(request);
Modify your app's UI to allow the user to submit a conversion request. You could add a button or a form where the user can enter the number of coins they want to convert and submit the request.
When the user submits a conversion request, write the request data to the "ConversionRequests" node in Firebase using the setValue() method. You can use the FirebaseAuth class to get the currently signed-in user's ID, and then create a new child node under "ConversionRequests" with the request data.
Related
I want to retrieve Firebase data within a range of say 1 week. I can query and get data for a day like today, but how about for a range of say 1 week? This is the code that am currenly using for retrieving data for a given day
String mDate = DateFormat.getDateInstance().format(new Date());
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("expenses").child(onlineUserId);
Query query = reference.orderByChild("date").equalTo(mDate);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
myDataList.clear();
for (DataSnapshot snapshot :dataSnapshot.getChildren()){
Data data = snapshot.getValue(Data.class);
myDataList.add(data);
}
todayItemsAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I cannot find a way of retrieving data for a given range. Someone please help.
The Realtime Database is not designed for complex SQL-like queries.
Not sure if your question refers to grouping results by week. If all you need is a set of results that start and on a certain date and end on another date, you can use startAt(...) and endAt(...) like described in this answer or the spec.
If you need anything more complex than that, you need to
either take all results and filter them in your front end/app code
or use a Cloud Function to do the filtering on the server and
passing the results to the front end.
(Not recommended) You can record the week number (i.e. 45_2020) as a separate field in the document, and filter by that. It's messy and you would have to trust that the front end enters correct info in the field.
I am making an Android app in Android Studio and I want to get specific data from the Firebase. I am trying to search through the Firebase Realtime Database to get all of the Users that have a usercode of 1234 and then getting their name. This is how I have it set up in Firebase:
Firebase Setup image link
Since I am searching for the data where the usercode = 1234 it will return (in the datasnapshot) all of the information about Joe and Lily (since they were the two users that had a usercode of 1234), but it shouldn't return information about Kevin. Here is how I did that:
Query getUsers = ref.orderByChild("usercode").equalTo(1234);
getUsers.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
//User with usercode = 1234 exists
} else {
//User with that Usercode doesn't exist
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
The datasnapshot, if converted to a string would have all of Lily and Joe's information I believe.
What I want to do is get the first user's name (Which would be Joe in this case) from that datasnaphot. My code will then use it through a few tests before going to the second user's name(Which would be Lily) and repeating the tests. Also, if there were 100 Users then I would need to repeat it for every one of those 100 that had a user code of 1234, so I probably need something repeatable.
So somehow I need to find the first value of the child's name from all of the Users that have a usercode of 1234 and then repeat until I get all of the names and run the test on all of them.
I am new to Stackoverflow, so please tell me if I am missing any information that would be helpful in answering the question.
---- EDIT ----
I have now figured out how to do this with Firebase Firestore. It has simpler queries and allows you to do more with the results. If anyone else has the same issue that I stated above, Firebase Firestore is something you might want to try out.
When using the following line of code:
Query getUsers = ref.orderByChild("usercode").equalTo("1234");
You are searching through the Users node, all users that have the usercode property set to "1234". This query will always return no results because you are searching for 1234 as a String and not as a number, as it is stored in the database. The correct query should be:
Query getUsers = ref.orderByChild("usercode").equalTo(1234); //No double quotes
I am passing a value (in this case another user's id) into a function. I need to be able to use the userid I passed to find the latest post by the userid searched for.
root:posts/generatedkey(post name, customerId, timestamp, etc)
I think the generated key is throwing me off. How can I bypass that to sort by customerid and timestamp to return the latest post record for the specified userId?
My code is below. The log is printing that there is no snapshot, but the record is showing up in my database.
private void getRequestInfo(String otherUserId) {
FirebaseDatabase.getInstance().getReference().child("posts").child(otherUserId).addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (!dataSnapshot.exists()) {
String noSnapshot = "No Snapshot";
Log.i(TAG3, "Snapshot Status=" + noSnapshot);
return;
}
...
The firebase documentation doesn't really specify how I can bypass the generated key... and I really don't think I can flatten my data any more than I have.
I am attaching the diagram of my firebase database.
https://drive.google.com/open?id=11p5xmLjHC49sqzvXYo3Au5GdNnULdnom
I want to update the value of the key "eventsregistered" upon successful payment.
The sole requirement is to increase the number of registered events of the user upon successful payment. The Payment function is handled by me. The problem that i am facing is that i can change the value of the child upon payment but the counter resets to zero evry time I launch the app. Please provide me a solution with the proper code. I have tried using .setValue method but it didn't work out.
I have tried with the following code but it didn't work out.
The following function is executed when the payment is done. The logic seems to be okay but when i reset the app the value of the key is reset to zero for no reason that could be known by me.
The code is attached below
int regEvents = 0;
String events_registered = "0";
private void btnAddRegisteredEvents() {
final String key2 = FirebaseAuth.getInstance().getCurrentUser().getUid();
final DatabaseReference databaseReferenceObj2 = FirebaseDatabase.getInstance()
.getReference().child("Users")
.child(key2).child("eventsregistered");
databaseReferenceObj2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
events_registered = dataSnapshot.getValue(String.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
regEvents = Integer.parseInt(events_registered) + 1;
databaseReferenceObj2.setValue(String.valueOf(regEvents));
}
Please help me with this code and help me to update the counter of registered evets upon a successful payment. Just a reminder, the payment function is already handled by me. What is required is the code that increments the value of the key "registeredevents" after a successful payment.
Your code isn't working because of the asyncronous nature of how the data is being retrieved from Firebase. You need to make sure the read completes before you try to use its result. As it is, you start the read, then immediately try to use the result.
But worse -- you aren't protected from someone else modifying the data at the same time after the read completes. You need to do this in a transaction.
There is a good example of a counter in the documentation. But its a little more complex than you need. I think this will work for you in place of where you currently call addValueEventListener and the rest of the function:
databaseReferenceObj2.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
long newValue = 1; // If it doesn't exist, assume zero and increment to 1.
String currentValue = mutableData.getValue(String.class);
if (currentValue != null) {
newValue = Long.parseLong(currentValue) + 1;
}
// Set value and report transaction success
mutableData.setValue(String.valueOf(newValue));
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
// Transaction completed
Log.d(TAG, "postTransaction:onComplete:" + databaseError);
}
});
This is written to deal with the fact that you are currently storing this number as a string, but it probably makes more sense to store it as a number (e.g. a Long).
I am trying to filter my Firebase data, my dataset is complex but here is a sample. I am able to retrieve data just fine but I am unable to filter that data any further using the Firebase queries. Here is a sample dataset:
Here is my query:
private double locStart;
private double locEnd;
Firebase mRef;
Firebase mRef1;
mRef = new Firebase("https://test.firebaseio.com/");
mRef1 = mRef.child("test");
final Intent intent = getIntent();
final Inputs inputs = (Inputs) intent.getSerializableExtra("inputs");
locStart = inputs.getLocLat() - 0.008983;
locEnd = inputs.getLocLat() + 0.008983;
Query filterData = mRef1.orderByChild("locLat").startAt(locStart).endAt(locEnd);
filterData.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Match matchd = dataSnapshot.getValue(Match.class);
Offer.setText(matchd.getfbName());
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
The reference mRef1 retrieves data perfectly, its only when I apply the query to it is when it retrieves null values, the data certainly matches the query, I have even hard coded the values but that does not seem to work either.
Am I missing something I should have setup on the Firebase console? I did setup an index and that solved a warning in my log which was suggesting me to set one up on the field meaning that Firebase is recognising the field and the index as well.
Firebase queries return a subset of the child nodes in a list.
So if you have a list of locations:
locations: {
location1: { lat: 42.010185, lon: -33.010185 },
location2: { lat: -11.19645, lon: 52.461219 },
location3: { lat: 33.14518, lon: -11.128746 }
}
You could query the locations with:
ref.child("locations").orderByChild("lat").startAt(-12.0).endAt(-10)
Your data is missing a level: you're querying test, but are missing the location1, location2, location3 level that I have under it. If you add such a level, your query will be able to match the child.
Your next problem is likely going to be that Firebase Database queries can only order by/filter on a single property. That means that for geo-queries, you can currently only filter on longitude or on latitude, which makes for only half a geo-query. I recommend that you look into GeoFire, which is our library for geo-querying. It combines latitude and longitude of each item into a single geohash value, which can then be queried.