Add value to specific key and datetime - java

I have an app where are few users. Each user can save item to firebase. But when a user save an item that item save under a date time child, and under user
name.
That's how my items are saved and users available
And instead of numbers (0,1,2) I want to appear date time and user name. Hope the question is ok i couldn't find any tutorial.
Here is my code :
databaseReference = FirebaseDatabase.getInstance().getReference("jsonData").child("listaVanzatoareProduse");
databaseReference.setValue(Util.getInstance().getVanzatorProduse());
Util.getInstance().getVanzatorProduse().clear();

The .child() method creates a new node if it doesn't exists. so you can simply do:
databaseReference = FirebaseDatabase.getInstance().getReference("jsonData").child("listaVanzatoareProduse").child(dateTime).child(userName);
databaseReference.setValue(Util.getInstance().getVanzatorProduse());

Related

How to update user data without changes into Firestore when it's checking for already existence in database?

I recently implemented unique username into my app when registering, all good far here, by the way I also need to set it to when the user is editting it's profile.
I tried to do the same thing, but I'm facing an issue here. The app don't let save the profile, because it's checking if the username's taken and, as we're already using one, it won't let us do it.
Ex.: My username is "bob", I changed my profile pic or my display name, so when I click to save, the app will do a username checking in the background and will not let me save it because the username is already taken, but the problem is that it's already my user.
I've tried to set this, but failed:
if (document.equals(setup_username.getText().toString()) || document.isEmpty()){
updateProfile();
Here's my code:
setup_progressbar.setVisibility(View.VISIBLE);
FirebaseFirestore.getInstance().collection("Users").whereEqualTo("username",setup_username.getText().toString()).get().addOnCompleteListener((task) -> {
if (task.isSuccessful()){
List<DocumentSnapshot> document = task.getResult().getDocuments();
if (document.equals(setup_username.getText().toString()) || document.isEmpty()){
updateProfile();
} else {
setup_progressbar.setVisibility(View.INVISIBLE);
setup_username.setError(getString(R.string.username_taken));
return;
}
} else {
setup_progressbar.setVisibility(View.INVISIBLE);
String error = task.getException().getMessage();
FancyToast.makeText(getApplicationContext(), error, FancyToast.LENGTH_SHORT, FancyToast.ERROR, false).show();
}
});
So how to get around this and only forbid it when I try to change my username to another that is taken? Like: "bob" to "bill", but "bill" is already taken, so it won't allow.
You'll need to have some indication in each Users document to indicate which user has claimed that specific name. Given that you store the username inside the document, ownership would typically be established by using the UID of the user as the ID of the document.
Once you have run your query to find the document for the username, you can then check the UID of the owner of that username against the currently signed in user. If the two UIDs are the same, the current user owns the username and is allowed to update the document.
Compare new username with previous username(store it in a variable while displaying user profile data), if both are same don't update it all else check for its uniqueness.
or if you don't have existing username data create relationship with that document and fetch previous username first.

How to show the new entry on the top list RecyclerView [duplicate]

I am developing an Android chat application in which I need to order the conversation details by the date. My firebase data structure is mentioned below.
Now I want to retrieve and show the data on the latest date on my RecyclerView from Firebase Realtime Database based on timestamp.
I have tried the following approaches.
final DatabaseReference nm =
FirebaseDatabase.getInstance().getReference("Transaction");
Query query = nm.orderByChild("Date").limitToFirst(5);
;
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
listData.clear();
if (dataSnapshot.exists()) {
for (DataSnapshot npsnapshot : dataSnapshot.getChildren()) {
Transaction ld = npsnapshot.getValue(Transaction.class);
listData.add(ld);
}
Tadapter = new TransactionAdapter(listData);
rv.setAdapter(Tadapter);
Log.d(TAG, "Total Count" + Tadapter.getItemCount());
}
}
}
I am developing an android chat application in which I need to order the conversation details by the date.
As I see in your screenshot, your Date property is of type String. This means that you cannot call:
.orderByChild("Date")
And expect to behave as it was a Timestamp. When you order String elements, the order that you get is always lexicographically. This means that Strings doesn't consider any sort of numeric values when sorting, especially when it comes to the dates, even if the dates contain numbers, as your first element does:
Date: "30/7/2021"
So using String values when querying your database it's not an option. However, I see you already have a Timestamp property. Maybe on that property, it was supposed to do the ordering. If that was not the case, I suggest you change the type of the Date property from String to Timestamp, as explained in my answer from the following post:
How to save the current date/time when I add new value to Firebase Realtime Database
Now I want to retrieve and show the data on the latest date on my RecyclerView
This means that most likely you need to reverse the order, meaning that all your transactions have to be displayed in your RecyclerView descending. In this case, there are a few options that you have, either on the server or on the client.
Assuming that you have changed the type of your Date property from String to Timestamp, then you can simply consider storing an inverted Timestamp value like this:
Firebase-root
|
--- transactions
|
--- 1
|
--- Date: 1627714194
|
--- invertedDate: -1627714194
See, the invertedDate property holds a negative value. Since by default, the elements are ordered ascending, to be able to order the transaction desecendiong, you should simply use:
Query query = nm.orderByChild("invertedDate").limitToFirst(5);
On the other hand, there are some workarounds that can be made to achieve the same thing on the client, as explained in my answer from the following post:
How to arrange firebase database data in ascending or descending order?
Query query = nm.orderByChild("Date").limitToFirst(5);
Firebase realtime database sorts in ascending order that means those 5 nodes that you'll receive will be the oldest.
I want to retrieve and show the data in latest date
Try using limitToLast instead which will return the last 5 documents after ordering the nodes by Date field i.e. the 5 latest nodes.
Query query = nm.orderByChild("Date").limitToLast(5);
You can read more about that at sorting and filtering data.

Firebase insertion overwites instead of appending

I have this database structure in firebase:
Its supposed to collect votes. I have several categories such as president, minister...etc. All people who vie for a "President" seat are listed using their unique keys, and Im trying to collect all voters emails.
This is my code:
public static void insertvote(String userkey, String categ, String candId) {
System.out.println("Returned candidate's userkey or ID: "+userkey);
System.out.println("Returned category: "+categ);
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference totalVotesRef = rootRef.child("votes").child(categ).child(candId);
Vote vote = new Vote(userkey);
totalVotesRef.setValue(vote.getVoterEmail());
}
The problem I have is that, when another user logs in and votes, instead of appending their email, its being overwritter to the existing email.
How can I resolve this?
Thanks
Instead of using setValue() at the location to collect emails, which always overwrites existing data, you should look into using push() first, which generates a new child using a random ID. You will want to become familiar with the documentation on working with lists of data, especially appending to a list of data.
totalVotesRef.push().setValue(vote.getVoterEmail())
Each email will appear under that randomly generated child value.

Firebase realtime database - getting data within time range

On my Android app, I have a calendar. When I click a date, I want to just show the items from that selected date. In other words, filter all other items out of the RecyclerView adapter and just show the ones for the selected Date.
Currently, when the activity opens, it just displays all items:
Query query = FirebaseDatabase.getInstance().getReference().child(FB_SUBJECTS).child(FB_PACKS)
PagedList.Config config = new PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPrefetchDistance(5)
.setPageSize(10)
.build();
//Initialize FirebasePagingOptions
DatabasePagingOptions<FB_Model> options;
options = new DatabasePagingOptions.Builder<FB_Model>()
.setLifecycleOwner(this)
.setQuery(query, config, snapshot -> {
FB_Model model = snapshot.child(FB_PROFILE).getValue(FB_Model.class);
addMarkerToCalendarView(getMilliFromDate(model.getstart_date()));
return model;
})
.build();
That will return all items at subjects/packs. Then from this query, I get some data from <userId>/profile/, like start_date and end_date, eg subject/packs/001/profile/start_date
Here's some sample data for start_date and end_date:
end_date; "05-04-2019"
start_date: "01-04-2019"
So, my problem is I want to filter these items, BUT I'm using FirebaseRecyclerPagingAdapter but that only pulls down a certain number of items at at time, eg 20. So I can't store all the results in one big list and filter them easily. So I'm relying on some built in functionality of Firebase.
Is it possible to alter my Query to achieve this? I know there's a startAt() and endAt() but not sure if they suit FirebaseRecyclerPagingAdapter.
So really what I need is a SELECT * from profiles where startDate = x and endDate = y;
Is that possible with the realtime DB on Android?
Thanks.
Is it possible to alter my Query to achieve this?
Sure it is but with some changes. As I see, you are storing in end_date and start_date properties the date as a literal String and this is not how you deal with dates in Firebase. So you should store the date as a Timestamp, which is basically a number, a long value. To see how you can achieve this, please see my answer from the following post:
How to save the current date/time when I add new value to Firebase Realtime Database
In the end, simply pass the needed timestamps to the startAt() and endAt() methods.
I know there's a startAt() and endAt() but not sure if they suit FirebaseRecyclerPagingAdapter.
You can pass to FirebaseRecyclerPagingAdapter any kind of query, including the one that has calls to startAt() and endAt() methods.

Firestore : How to add a field to the auto generated id in firestore when user clicks on a button in android

I implemented the FCM notification to the user in Cloud Functions. By using Cloud Functions I added a document(auto generated id) into the Firestore. I need that document id to add another field as status in the same document from android app.
I had a database path like:
/deyaPayUser
{authid}
/Split
{auth id }
/Received Invitation
{auto id}
. Amount: 10
. PhoneNumber:987654321
These is the data already exist . Now I need to add a field in that document. How to get the current document id of the user
Status : true
According to your comments, in order to find that particular document, you need to create a Query based on property within that document like this:
Query query = yourCollectionReference.whereEqualTo("PhoneNumber", 987654321);
This query will find the user that has the phone number 987654321.
Now just simply use a get() call, get the id and make the update:
Map<String, Object> map = new HashMap<>();
map.put("Status", true);
yourCollectionReference.document(documentId).update(map);

Categories