how can i update another user balance base on id in firebase? - java

i am doing android studio project using Firebase,currently i had done with the registration and login,but my function is to transfer amount to another users with balance.
So what i need to do is to find the way to modify/update the balance content(value) after transferring the amount to another user.
but i do some researched they say Firebase only can only read/write with own user account.
assume i have already login to user1,and want to do the transfer to user2.
thanks.
-Users
-AsjdnskkhdiioAndmmnekwas
Name:"User1"
email:"user1#hotmail.com"
uid: "Adjshdkjwwnekwihwoi4kdnw4l2"
age:20
Balance:100
-DdmkenklahaoinskaAnmdmls
Name:"User2"
email:"user2#hotmail.com"
uid: "Cbdnaknekmmalsmdlen1qnio2"
age:21
Balance:100
-------------------------------------------------------------------
**how to become:**
-Users
-AsjdnskkhdiioAndmmnekwas
Name:"User1"
email:"user1#hotmail.com"
uid: "Adjshdkjwwnekwihwoi4kdnw4l2"
age:20
Balance:50
-DdmkenklahaoinskaAnmdmls
Name:"User2"
email:"user2#hotmail.com"
uid: "Cbdnaknekmmalsmdlen1qnio2"
age:21
Balance:150

Remember that you are manager all information of all users (in your database).
Use DatabaseReference setValue() method to update information inside database like this:
private DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
String senderId = "sample_id_sender";
String receiverId = "sample_id_receiver";
mDatabase.child("users").child(senderId ).child("Balance").setValue(new_balance1);
mDatabase.child("users").child(receiverId).child("Balance").setValue(new_balance2);
How to know id of receiver??? it depends on your situation, example, you want to send 1$ to user whose name is "User2". You must find user2 id in list of users, in you database, I think these guide is good for you:
https://firebase.google.com/docs/database/android/read-and-write
https://firebase.google.com/docs/database/android/lists-of-data

Interesting problem. I think you can use a combination of a modified data model, a transaction and server-side security rules to implement this.
Step-wise:
Since you'll need to know the current balance of both users in order to determine their new balance, you'll need to use a transaction.
You'll need to store the actual transaction in some way, as otherwise the server won't be able to validate the write. The minimum info here is from UID, to UID and amount.
In your security rules you should then modify that the total balance across the two accounts is unmodified across the transaction. For this you need the data from step 2, as you otherwise can't know the to account.
Finally, in your security rules you'll want to validate that the only account whose balance can go down is the one of which the current user is the owner. In rules something like "balance": { ".validate": "data.child('uid').val() == auth.uid || newData.child('Balance').val() > data.child('Balance').val()" }
Scalability may be an issue though, as it's modifying nodes in multiple child nodes which means the transactions run across the entire top-level branch.
Also see:
Is the way the Firebase database quickstart handles counts secure?

Related

Firebase Realtime Database Download Data Size Problem

1.DatabaseReference db=FirebaseDatabase.getInstance().getReference("users");
1.Query query = db.orderByKey().equalTo(uid);
2.FirebaseDatabase.getInstance().getReference("users").orderByChild("token").equalTo(toKen)
Does any one of the above two codes written in Java Android Studio send the entire "users" node of Realtime Database to the client Android App or Only the the Fetched Records will be send to the client Android App. It Seems like that it sends the complete "users" node to the client Android App, because my realtime database bill is quite high and customers are low.
It seems you are looking for orderByChild(). To get the child node where the value of uid is equal to passed UID, try this:
DatabaseReference db=FirebaseDatabase.getInstance().getReference("users");
Query query = db.orderByChild("uid").equalTo(uid);
The documentation says,
Method
Usage
orderByChild
Order results by the value of a specified child key or nested child path.
orderByKey
Order results by child keys.
The second query looks fine and should fetch the node where the value of token is equal to the supplied token.
If the download size is higher than you'd expect based on the number of query results, check if you've defined an index on the token property. If no such index exists, Firebase will download all data under users to the client, and perform the sort/filter there. If an index is declared, the ordering/filtering is done on the server.

How to display username and email from firebase in android

i am trying to get username and email for single user profile.
I think that firebaseAuth.getCurrentUser().getUid() return uid that is not the same as uid in FirebaseDatabase. You can user Query.
For example:
Query q = firebaseDatabase.child("users").orderByChild("email").equalTo(firebaseAuth.getCurrentUser().getEmail());
You should use addChildEventListener instead of addValueEventListener, and write the code inside onChildAdded.
You can find the explanation from documentation:
When working with lists, your application should listen for child
events rather than the value events used for single objects.

How to link up users in Firebase to information defined in other Java classes?

My Firebase database currently looks like this.
Main Branch 1
(Users' Information)
{Users
Individual Users
Username, Email, Password}
Main Branch 2 (To-Dos)
{Event, Description}
The issue now is that even though I can authenticate users, whenever I log into the app, users are not tagged to their to-dos within the app. Hence, the to-dos are always static.
Ideally, I would like to either:
1)Keep the branches and tag the main branch 2 to main branch 1 based on a certain type of authentication (most probably username, as it is unique)
2) Incorporate main branch 2 into main branch 1 and just have it look like this.
{Users
Individual Users
Username, Email, Password
{Event
Description}
}
I have a feeling that option 2 would be both easier to implement, as well as less messy to manage the app in the future.
How should I go about doing this?
The to-do branch can be like this:
to-do
userID
randomID
name: userX
event: Meeting
Description: meeting about the next project with usery
userID
randomID
name: userG
event: football match
Description: Watch the match with my children
Thus the userid and name are now linked with the events.

Hiding information for a particular user

I am using RESTFUL webservices using Spring framework.Some information is displayed on the user interface using the data returned by webservices. There is a webservice, which gets the usernames and their roles from the database. For a particular user , I would like to have all the webservices display data in the form of ####,#### for first name,lastname ; ##/##/#### for date of birth etc. Since I am using JDBC to connect to the database, here's what I was thinking of doing:
Should I consider passing an additional parameter (maybe sending a value 0 or 1 ; 0 for all other users and 1 for user for which I want to hide the information) to each and every GET webservice so that when it comes to getting data from the database in the JDBC code part,I could check whether the flag is set to 1 or 0 and based on this, I could do something like this in the JDBC code :
// Code for a case when flag is set to `0`. Hence retrieving information from the database.
while(rs.next()) {
EmployeeList empList = new EmployeeList();
empList.setEmpId(empId);
empList.setEmployeeName(rs.getString("name"));
employeeList.add(empList);
}
// Code for a case when flag is set to `1`. Hence hiding information and not retrieving information from the database.
while(rs.next()) {
EmployeeList empList = new EmployeeList();
empList.setEmpId(empId);
empList.setEmployeeName("####,######");
employeeList.add(empList);
}
I am wondering, if this is an appropriate way to achieve my task or is there some other way around?
Edit:More clarifications on my requirements:
I am using jqxWidget in the UI to display the information I am getting from a RESTFUL webservice in JSON format. For example, let's consider this example and the screenshot for better understanding of my requirement:
1) Let's say I am getting all the information from the JSON response which I am populating in the jQXWidget as shown in the screenshot above.
2) In the above widget, I would like to hide say for example, First Name, Last Name and Quantity like the following:
First Name = XXXXX
Last Name = XXXXX
Quantity = ####
In my application, if a user clicks on a particular row , a new page is displayed with some additional information. After click, new sets of web services are called and those web services takes First Name, Last Name and Quantity as input parameters. My concern is that, if I somehow replace the First Name with XXXXX, Last Name with XXXXX and Quantity with #### using any approach, when a user clicks on any of the row of the widget, the next set of web services
are going to get XXXX and #### as input and eventually will fail. Please correct me if my understanding until this point is not correct.
Thanks
I am using Spring 4.2.5 version.
This depends on what sort of information hiding you want to achieve. Typically you shouldn't do this manually.
You can use, for example, role-based authorization. Exact details depends on the web-service framework you are using.
For spring MVC, you can use something similar to this:
Custom authorization in Spring MVC

Filtering by grandchild property in firebase [in android]

CONTEXT :
Hi, I'm currently working on an Android project backed by Firebase.
I have set up a denormalized data structure that relates polls to users (many-to-many relationship) via way of votes. Here is an image displaying the votes path of my database. The structure is as follows :
votes -> [pollUid] -> [votePushuid] -> vote object
So in this example we have a single poll that has 4 votes.
I want to run a check to see if a user has already voted on a poll. In order to do this I fetch the pollsUid, then run through its votes to see if any of them contain the voterUid property == to their user uid.
This is done as follows :
FirebaseHandler.getInstance().getMainDatabaseRef()
.child(FirebaseConstants.VOTES) //votes root
.child(pollKey) //polluid
.orderByChild("voterUid")
.equalTo(FirebaseHandler.getInstance().getUserUid())
.limitToFirst(1)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()) {
If the datasnaptshot exists then we know that the user has already voted on this poll and can handle it in the Java logic.
PROBLEM :
The datasnapshot received by onDataChange is always null (ie does not exist) when searching for a specific user's vote on a specific poll. I know for a fact that the vote exists in the db through inspecting the data, and that the userUid is correct via debugging. Removing the equalTo and limitToFirst returns all of the votes for the poll without a problem so clearly the stem of the ref is correct. This implies to me that the issue is created by one of the two methods just mentioned. Even stranger is the fact that this approach does work at certain times, but not at others.
QUESTION :
How do I return a list of firebase stored objects filtered by a grandchild property? If this is not possible what would be the more appropriate datastructure for this problem?
On a further note I've seen people taking the approach of using Query instead of Databasereferences. Perhaps this might have something to do with the current issue.
Your query is correct. I have no problem running that query using my own DB. It's probably the userId doesn't match. DatabaseReference extends Query, that's why you can access Query's methods.
A database structure alternative would be
{ "users_votes": {
"<userId>": {
"<pollId1>" : true,
"<pollId2>" : true,
"<pollId3>" : true
}
}
}
Set the value to that node once the user voted to a poll.
To check if the user has voted for a poll
usersVotesRef.child(FirebaseHandler.getInstance().getUserUid())
.child(pollKey).addListenerForSingleValueEvent(valueEventListener);

Categories