How to correctly nest data and write to Firebase - android

I have some Edittext that allows the user to enter data:
AppName
Date
Title
Quantity
User
I started a new Firebase project and it is currently a blank slate.
I am setting up my Firebase instance like this:
private DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReferenceFromUrl("https://myapp.firebase.io");
How I want it is everytime a new adding occurs, I would like to add it like this (AppName is the common ground for all entry):
AppName
Date
Title
Quantity
User
Date
Title
Quantity
User
...
...
AppName
Date
Title
Quantity
User
Date
Title
Quantity
User
...
...
How can I do the following:
The first time it is added, the AppName will be the parent node, and
anytime after Firebase should check to see if the parent node exist
and is the same and add it to that, otherwise create a new parent node
and add the children node to the new parent node.
I currently have my auth set up like this:
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
I had to change to true for my app to write to Firebase.
How can I:
Not register the user but only allow the app to able to write to
Firebase.
EDIT:
I am doing the following:
mDatabase.child("AppName").setValue(etName.getText().toString());
mDatabase.child("AppName").child("Date").setValue(etDate.getText().toString());
mDatabase.child("AppName").child("Title").setValue(etQuantity.getText().toString());
mDatabase.child("AppName").child("Quantity").setValue(User.getText().toString());
mDatabase.child("AppName").child("User").setValue(etUser.getText().toString());
Instead of adding, it is overwriting the previous entry. How can I append.

If I understood you, you need that not registered users could edit your database on Firebase and how to know If you added an ID.
First of all, as Ishan Fernando said, If you add data with the same id, this data will be overwrited, and using the push method, Firebase will create an unic ID to add you data
Read this: https://firebase.google.com/docs/database/android/read-and-write?hl=en
This Gist, thanks to the user realgt, could help you to know if the Appname exists or not: https://gist.github.com/anantn/4323949#gistcomment-998628
This will get all your data and you could check if you need add it or not
And, if you don't want to register users, but you need them to write the database, I think that you need to register them as anonymous users:
https://firebase.google.com/docs/auth/android/anonymous-auth
Firebase needs registered users (using social networks, email o anonymously) to modify it, so try the anonymous method. The problem is when the user get out of your app, this user will keep registered on your database. So, I recommend you, (Please, correct me if I'm wrong) to erase the user when onStop starts and create it again when onReady starts.
I hope it helps.

Related

Firebase rule resolving wrong

I'm trying to set firebase rules to my database but i'm having problem with data and newData
According to firebase:
newData A RuleDataSnapshot corresponding to the data that will result
if the write is allowed.
For .write and .validate rules, the newData variable gives you a
RuleDataSnapshot corresponding to the data that will result if the
write is allowed (it is a "merging" of the existing data plus the new
data being written).
So I have the following rule:
"users_details":{
"$uid":{
".write":"$uid == auth.uid && newData.exists()",
".read":"$uid == auth.uid",
".validate":"newData.child('auth').hasChild('crsfToken')",
}
User has a field auth which has a field crsfToken... so everytime someone writes a user i want to ensure the "edited" user will have auth/crsfToken
Ok.
Let's say a have an actual valid user abc.
Then i want to set another field on abc, that has no relation to any rule...
lets say: abc.field.subField = 1
so what I am doing is:
FirebaseDatabase.getInstance().getReference(Firebase.NODE_USERS_DETAILS).child(user.getUserid()).child("field").child("subField").setValue(1);
this isn't changing auth nor crsfToken but i'm getting Permision Denied
When I do a simulation on console, i see that isn't writing because the validate rule is denied
why? is there any way to debug firebase rules and see what is newData on a simulation?
Rules are resolving ok :) Because rules will be checked for all data manipulations on user_details/UID/*. So if you update user_detail/UID/field/subField, your rules will be checked and you will get access denied as you are. You said that you want to check for newData.auth.crsfToken and you are doing that indeed, but now you want to update field/subField without checking that? In which case you don't want to check crsfToken existence?

Copy data from one child node into another Firebase

I am working on an Android application where there are two types of user. I differentiate them into the system by using the field UserType. I have a requirement where I have to copy data from one child node into another. I am using Firebase for my backend. I have gone through other answers but this requirement is unique in a way that, I want to copy data only on a particular node. Attaching the Firebase database structure
In this structure, if you can see I have expanded 2 child nodes of "users". One of the child has userType as Standard User and other child has userType as Guardian User.
1) I want to copy the "fullNameGuardian" child alone from the user with key starting with "L4bTr6q" to the user with key starting with "dC9Mq"
2) I want to copy the "standardEmail" child alone from the user with key starting with "dC9Mq" to user with key starting with "L4bTr6q".
And everytime I add a new user, the user can be with one of the userType "Standard User" or "Guardian User". So is there a possibility like I do it for every new user?
I am having difficulties figuring out how to do this. Any help is appreciated. Thanks a lot in advance.
I think you could save the other structure when you save the first one. For instance,
Save - node1/child
Update - node2/child
//and so on
Another way is using Firebase functions(Real database triggers) in order to automatically do something after something else had happened. Check it out.

How the linkWithCredential works? How does it work with Rules?

I found this documentation that explains about how to link anonymous user with a new registered user, but I couldn't understand how it works.
From the explanation also found here, I got a big picture like below (please correct me if I'm wrong):
User login with anonymous: got userUid (just for example) ANONYM-USER-UID
User than add data to shopping cart like below:
data
-- shoppingCart
-- ANONYM-USER-UID
-- <push-id>
-- itemUid: <item-uid>
-- count: 2
-- <push-id>
-- itemUid: <other-item-uid>
-- count: 1
-- OTHER-USER-UID
-- .......
with rule: Only appropriate UserId can access shopping cart
"rules": {
"shoppingCart" {
"$userUid": {
".read": "auth.uid == $userUid"
}
}
}
Before checkout, user "forced" to register/or login, the AuthCredential then retrieved then linkWithCredential called. User than use a new userUID for example REGISTERED-USER-UID
The question is, whenever the client code query shoppingCart/REGISTERED-USER-UID will it retrieve the item list of shoppingCart/ANONYM-USER-UID? Will the Rule allow it?
What if a more complex rule is applied, for example, the rule becomes
-- Only appropriate UserId can access shopping cart, but userUid must not in blackList child.
"rules": {
"shoppingCart" {
"$userUid": {
".read": "auth.uid == $userUid && root.child('blackList').child($userUid).val() == false"
}
}
}
With a logical restriction like that, will it successfully return the list?
I think you are slightly confused regarding the flow of Anonymous-User login and then linking it with new Auth Credentials. Here is what I have experienced.
When a user logs in as anonymous then system assigns a unique ID. Now when the user decides to sign up with some new auth credentials then all that happens is that previous UID generated at time of anonymous login gets assigned or linked to those new credentials.
So in reality no new UID is created and you are good to go.
Do let me know if this info was helpful.

How to create a custom user property for firebase?

The help section on the firebase console says that
Firebase app can have up to 25 uniquely named user properties (case-sensitive). You should use properties for non-variable attributes, such as “handedness=right”, “spender=true”.
In the firebase documentation a property is said be to set this way
mFirebaseAnalytics.setUserProperty("favorite_food", mFavoriteFood);
Does this mean that for every user property named k and having a value v, we need to create a user property in the console as "k=v" and set it in the code by setUserProperty(k,v)? So, for a user property called "favorite_food" having the possible values as "pasta" and "pizza", one needs to create two new user properties in the console as "favorite_food=pasta" and "favorite_food=pizza" and set it by, say, setUserProperty("favorite_food","pasta")?
For every User Property named k, you need to register an entry in the "User Properties" tab in Firebase Analytics. For every user with User Property value k=v, you need to call setUserProperty(k,v).
After calling setUserProperty(k,v) (and after logging some events), you will be able to filter your Analytics reports by applying a User Property filter for k=v (favorite_food=pizza) .
Creating an entry for User Property k in the console will allow you to
filter based on k=v0, k=v1, ... for all valid values of k.

Parse: How to add object to the user, who is not not the current user

i have created my app, in which I have created several users. The challenge is, I need to construct the app in a way that, while I am logged in as a user (say User A), I can add input an object into another user (say User B). So, while am logged in as user A, I can input the data that will be saved into one of the empty field, of User B. Can you assist which way, I can arrange this? In short, how can I create an object to associate with the User B.
Here is the thing, while I am logged in as User A, I want to add "Scores" for both user A and B. for instance, if the user A's score is 7, and B's score is 20, I could add the scores while logged in the activity A, and they will be added in the field "Scores" of the corresponding users.
you should go for parse cloud code which is written in java script
refer this link to know more
https://parse.com/docs/js/guide#cloud-code
then you just edit main.js
deploy and call that cloud code from your code
// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("updateTable", function(request, response) {
var currentUserId=request.params.currentLoggedinUser;
var userToBeUpdatedId=request.params.userToBeUpdated;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userToBeUpdatedId });
user.addUnique("followers",currentUserId);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
deploy this code using comand "parse deploy" from terminal.
call this code from your code like
ParseCloud.callFunction("updateTable", params);
i hope it will help.
The way that Parse is setup by default is so that only the current users data can be editted in the User table. You could probably change the settings for the table however, this could cause security issues.
What I would suggest would be to create a 'Scores' tables. There you could have a row for each user. with a 'userID' column which contained the objectId of the user to reference the user. You could then have a score column which you could update whenever you wanted.
Alternatively to storing the objectId of the user in the userID column you could make an association between the Scores row and the user. See the Parse documentation for how to create associations. https://parse.com/docs/android_guide#users-associations

Categories

Resources