android firebase unable to add second child - android

My code:
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NewQuestionData nqd = new NewQuestionData(question.getText().toString(),keywords.getText().toString(),description.getText().toString());
databaseReference.child(firebaseUser.getUid()).child("question"+Math.random()).setValue(nqd);
}
});
Every time I insert value into the database, it fails.
Problem is here:
child("question"+Math.random())
I want to add unique ID with every question.
Following works fine:
child("question")
Please share your valuable suggessions, How to insert unique child for every new question inserted into the Firebase Database.

Try this.
String key = databaseReference.child(firebaseUser.getUid()).child("question").push().getKey();
databaseReference.child(firebaseUser.getUid()).child("question").child(key).setValue(nqd);
// key is unique every time you add your new question.
For more info you can visit https://firebase.google.com/docs/database/android/read-and-write
OR
you can use System.currentTimeMillis()
It will give timestamp in long and is always unique.
databaseReference.child(firebaseUser.getUid()).child("question"+System.currentTimeMillis()).setValue(nqd);

The problem is that the random generator function Math.random() generates values between 0 and 1 which would have the decimal point - .
Now this decimal when added to a string would look something like question0.0001
If you check the Firebase documentation, you would see that . is a forbidden character in a key. So this would be your problem. If you at all want to generate a random value, use something which will generate random values from 0 to INTEGER_MAX.

To insert a child with a unique key without having to worry about it, call Firebase's push() method. See the Firebase documentation on appending data.
Your code could be:
databaseReference
.child(firebaseUser.getUid())
.push()
.setValue(nqd);
This will generate a unique key of the format specified in this blog post: The 2^120 Ways to Ensure Unique Identifiers.
If you still want to use the question prefix, you can use push() as a separate call (it's a client-side call that doesn't connect to the Database):
String key = databaseReference.push().getKey(); // gets a unique ID
databaseReference
.child(firebaseUser.getUid())
.child("question"+key)
.setValue(nqd);

Related

Why does .event.set("fieldName", ObjectValue) not storing any data in Google Calendar API android?

I successfully intergarted Google Calendar API. I'm able to do CRUD. But now because of some requirements, I want to send some unique id to each events while creating from android app. For that I found one method called .set() this is a key value pair.
Event event = new Event()
.set("appointment_id", 55475)
.setSummary(summary)
.setLocation(location)
.setDescription(des);
But while fetching, I'm getting all data except event.get("appointment_id")
Why, even it is setting also. [If I'm doing here before executing insert like this: evetn.get("appointment_id"), I'm getting value, because this is locally I'm chocking]
I checked through debugging as well. See below:
But, I'm not getting when I'm fetching all events from Google calendar:
List<Event> items = events.getItems();
You are using the set method, but this is just an override of the com.google.api.client.json.GenericJson class, I believe this will only add this key-value to the final JSON which will be ignored by the API (as it is not an expected field).
Sincerely I don't know what is the point on creating a custom id when there is one directly integrated in calendar.
If you take a look at the insert method you can see that there is one field called id:
Opaque identifier of the event. When creating new single or recurring events, you can specify their IDs. Provided IDs must follow these rules:
characters allowed in the ID are those used in base32hex encoding, i.e. lowercase letters a-v and digits 0-9, see section 3.1.2 in RFC2938
the length of the ID must be between 5 and 1024 characters
the ID must be unique per calendar
Also in the same description for the field:
If you do not specify an ID, it will be automatically generated by the server.
My point being that if you need unique ID for events in calendar there is a built in method that will create them for you. And even if you need to supply your own id's you can do so informing this field.
Let me suggest you the official guide on event creation in which there is a more detailed view on the option you can take creating an Event.
Also look at the documentation for setId as this is the method you should be using instead of set.
Example:
Event event = new Event()
.setId("55475") // This has to be type String
.setSummary(summary)
.setLocation(location)
.setDescription(des);

Cloud Function to sort the Firebase Child from inner child

I need to have one problem sorted out. I want a cloud function, where I need to loop through every Posts that has uniqueID and I want to sort those uniqueID's according to the value of TotalReactions. To me more vivid, suppose, the first post has totalReactions = 5, and second one has totalReactions = 6, then I need to have another RealTimeDatabase "PostArranged" which sorts them in descending order, so second post which has Total Reaction would be in first and then follows the one which has lesser TotalReaction...
Here is how my firebase realtime database looks like:
Posts
-L29TD-nsUYRu3wYcCQl
Caption: "First Screenshot"
CurrentUserReaction: "notreacted"
Image: "https://firebasestorage.googleapis.com/v0/b/nep..."
ReactingUser
<user-id>:"1"
<user-id>:"2"
Time: "13:40:54"
TotalReactions: "2"
Unique: "-L29TD-nsUYRu3wYcCQl"
UserPhoto: "https://firebasestorage.googleapis.com/v0/b/nep..."
Username: "Me"
Any help would be appreciated ..
This is not a good way to do what you want to do. In this method the database has to be sorted to another "ArrangedDatabase" every time a reaction is added which will happen in a high frequency. So it will be very expensive to do this with Cloud Functions.
Instead use orderByChild(), orderByKey(), orderByValue() to sort data when you're querying data.
Sorting data - Firebase documentation this show it quite well.
For anyone who want to do this in your RecyclerViewAdapter provided by Firebase, it is easily done... When you pass in those 4 parameters. Do not pass the database Reference, instead, make a new query, and make sure to sort that thing either by OrderByChild(), OrderByValue() or anything you want to order by... i.e.
In my case, I will do something like this:
q = mDatabaseReference.orderByChild("TotalReactions");
and pass q as parameter inside FirebaseAdapter, like this:
FirebaseRecyclerAdapter<Posts,PostViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Posts, PostViewHolder>(
Posts.class, R.layout.each_post_layout , PostViewHolder.class, q
) {
.
}

Firebase overwrites existing records instead of appending them

I am a bit new to Firebase and so have been playing around with to help myself get more acquainted with it. So while I was playing around with realtime databases, I was trying to append data to the JSON tree. The code is as below
mSaudi.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
count++;
mHistory = mChildRef.child(Integer.toString(count));
current = riyadh;
mChildRef.setValue(riyadh);
mHistory.push().setValue("riyadh");
}
});
The tree which I require is something like this:
value:
1: some text
2: some other text
But what's a actually happening is this:
value:
1: some text
and on updation
value:
2:some text
the previous entry gets erased
I have tried changing the references in various ways but to no avail. Any help in this regard would be appreciated.
If you would like to save both values, you have to save them using a variable such as a Hashmap. If you save a string and then try save another one under the same branch, it will delete everything previously saved. So try the following
HashMap<String, String> map = new HashMap<>();
map.put("1","String");
map.put("2","String");
mHistory.push().setValue(map);
This will save both the strings without deleting one.
If you would only like to add one String
mHistory.push().child("1").setValue("Your first String");
The biggest problem with this though is that everytime you use push() you generate a random key, so you would have to save the key as a string and use it as a reference in your child.
When you set a value on Firebase, it is going to replace everything in, and under the reference.
Let's say that you have a house value, with 2 childs: Color and Size.
If you want to edit only the color value, before the setValue(), you will have to change the reference you are pushing to.
If your reference was getReference().child("houses") and you push something there, it's going to replace everything there and below it. The way to do it is create a new reference (or update the previews one) like this: getReference().child("houses").child(houseKey).child("color") and push your String there.
In your example, you will need to add the field you want to change as a child before the push() method.
The other way was already told by #Janwilx72 and is getting the whole object, updating the value locally and pushing the entire object again.
You can try this
mChildRef.child("2").setValue("some text");
It should be appending new item instead of overwriting them

Can't set KeyConditionExpression parameter in DynamoDb for Android

I'm using the Amazon AWS DynamoDB for android, however, there's no way for me to set the KeyConditionExpression for a query.
See [http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/mobileconnectors/dynamodbv2/dynamodbmapper/DynamoDBQueryExpression.html][1]. The DynamoDBQueryExpression class is missing a withKeyConditionExpression() method.
I'm trying to make a query against dynamodb table but there's no way for me to set the key condition values.
Unfortunately keyConditionExpression No Longer exist for Java / Android. I wasted a significant amount of time because it still exist for Objective-C / iOS.
And since all AWS docs still refer to it, I thought I was in error. Once I have the new code written and working, I will document the replacement here.
The keyConditionExpression is set as follows:
AWSDynamoDBQueryExpression *queryExpression = [AWSDynamoDBQueryExpression new];
queryExpression.keyConditionExpression = #"#bookId = :bookId";
queryExpression.expressionAttributeNames = #{
#"#bookId" : #"bookId",
};
queryExpression.expressionAttributeValues = #{
#":bookId" : self.selectedBookId,
};
I encountered the similar problem for my Android Application where .withKeyConditionExpression() method was giving an error. Instead of that, I used:
TestTable object = new TestTable();
object.setHashKeyValue("12345"); //Set the value for HashKey
String queryString = "soverflow";
Condition rangeKeyCondition = new Condition() .withComparisonOperator(ComparisonOperator.BEGINS_WITH.toString())
.withAttributeValueList(new AttributeValue().withS(queryString.toString()));
DynamoDBQueryExpression newQueryExpression = new DynamoDBQueryExpression()
.withHashKeyValues(object)
.withRangeKeyCondition("AttributeName", rangeKeyCondition)
.withConsistentRead(false);
PaginatedQueryList<TestTable> result = mapper.query(TestTable.class, newQueryExpression);
The Point is that If you are Querying a table, the HashKey and the RangeKey will be the Partition Keys of the table and If you are Querying an Index, the Hash Key and the Range Key will be the partition keys of the Index.
Make sure to use the Annotations properly in the Table Class and to add Index's ARN to the Policy for authorization.

How to add a specific key with a specific value in a firebase database with Android?

I have a realtive simple Firebase database, in which i have 2 models. A ListModel and a UserModel. In my Lists, i'm using push() method to generate unique ids. Each unique id i want to be added as a key and "true" as it's value under Users/gmail#gmail,com/Lists.
When i add the first list, the database looks like this:
And everything works fine, but when i try to add another one, the database looks like this:
In Users/gmail#gmail,com/Lists, the first one is overwritten by the second insert. How can i add the specific id and the specific value, as a new item as shown below?
And this is my code:
final UserModel um = new UserModel();
um.setUserEmail("gmail#gmail,com");
userDatabaseReference.setValue(um);
ListModel lm = new ListModel();
lm.setListName(listName);
listKeyDatabaseReference = listDatabaseReference.push();
listKey = listKeyDatabaseReference.getKey();
listKeyDatabaseReference.setValue(lm);
listDatabaseReference.child(listKey).child("Users").child("gmail#gmail,com").setValue("true");
userDatabaseReference.child("gmail#gmail,com").child("Lists").child(listKey).setValue("true");
Thanks in advance!
Check the official doc:
For basic write operations, you can use setValue() to save data to a specified reference, replacing any existing data at that path.
Your problem is here:
userDatabaseReference.setValue(um);
In this way you are overriding all children in the userDatabaseReference path.
It means that the first record in Users/gmail#gmail,com/Lists is just deleted when you are adding the second one.
Before using the
userDatabaseReference.setValue(um);
you can check if the record exists.
If doesn't exist use the setValue to add the user-model with all its data.
If it exists, just skip this step and add the data in the lists path inside the same user.

Categories

Resources