I want to query Cloud Firestore data in last 7 days. I am using server timestamp of Firestore also storing the time in millis.
CollectionReference IOTransactions = db.collection(userID)
.document("userData").collection("StockTransactions");
Query transactionsQuery = IOTransactions.orderBy("timestamp",Query.Direction.DESCENDING);
transactionsQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, #javax.annotation.Nullable FirebaseFirestoreException e) {
if (e != null) {
Log.w("FirestoreDemo", "Listen failed.", e);
return;
}
for (QueryDocumentSnapshot doc : queryDocumentSnapshots) {
if (doc.get("timestamp") != null)
transactionsList.add(doc.toObject(StockTransaction.class));
Log.d("Firestore", "Added item");
}
if(transactionsList.size() < 1 )
emptyTransactionsPage.setVisibility(View.VISIBLE);
Log.d("Firestore Reading", "Successfully fetched");
adapter.notifyDataSetChanged();
pb.setVisibility(View.INVISIBLE);
}
});
How can I query the data created in last 7 days?
I am using server timestamp of Firestore also storing the time in milliseconds.
So if you are storing the timestamp in milliseconds, you are doing it wrong.
How can I query the data created in last 7 days.
To be able to query your database according to a periode of time, your timestamp property should be o type Date and not long. To see how you can achieve this, please take a look at my answer from this post.
Once you have the property set correctly, a query that looks like this should do the trick:
IOTransactions.whereLessThan("timestamp", now).whereGreaterThan("timestamp", sevenDayAgo);
In which now and sevenDayAgo are two Date objects representing the present time and a moment in time seven days ago.
According to My Knowledge you can also use the following query to get the result
Query query = mdb.collection("$YOUR_COLLECTION_NAME").orderBy("$YOUR_FIELD")
.whereGreaterThan("$YOUR_FIELD",$Begin_Date_Object)
.endAt($YOUR_DATE_OBJECT);
Note: You need to declare a Java.Util.Date object to endAt field and
orderBy must be always before startAt() or endAt() method.
The end at searches all documents containing the end at value of field in orderBy
Related
Here in the Firestore databases is a collection called "Users", In that collection, there are 29 documents(States) and in each of that documents there are many collections(Districts). This collection includes many documents these documents include the user's data along with numbers).
so how do we check the phone number that has already been added to the database?
I write something like this
FirebaseFirestore firestore = FirebaseFirestore.getInstance();
CollectionReference usersRef = firestore.collection("Users");
String phoneNumber = "1234567890";
usersRef.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Map<String, Object> data = document.getData();
for (String key : data.keySet()) {
Object value = data.get(key);
if (value instanceof String && ((String) value).equals(phoneNumber)) {
isRealAvailable = true;
Toast.makeText(OtpActivity.this, "Number found", Toast.LENGTH_SHORT).show();
// Phone number found
break;
}
}
}
} else {
isRealAvailable = false;
Toast.makeText(OtpActivity.this, "No number found, create an account!", Toast.LENGTH_LONG).show();
}
// Handle error
}
});
(the number is not a String value)
I don't know how to retrieve these details from different document names.
How do we get the Phone Number from the document? if it exists.
What I wanted is, I'm building a blood donors app, where people can register using their phone numbers. From different countries. So when a user sign-up with proper details, he can go to the main screen. Whenever he logout and login, he doesn't need to update the details again. As we know phone number login and signup are the same. Also, I want to separate the states and places in different documents and collections. I added the location permission and perspective codes so the country and states are chosen automatically. (will get the users location)
When you're calling get() on the following collection reference:
CollectionReference usersRef = firestore.collection("Users");
It means that you're trying to get all user documents that exist in the Users collection. As soon as you get all users, you then check the phoneNumber against the one that you find in the database, which is bad since you'll need to pay for a document read even for the users that do not have that particular phone number. What you have to do instead is to create a query that should only return the documents that you are interested in.
On the other hand, your actual database schema isn't quite helping you to achieve that. In the NoSQL world, we are usually structuring a database according to the queries that we want to perform. So if you need to get all users from Brooklyn / New York that have a particular phone number, I would recommend you have a schema that looks like this:
db
|
--- users (collection)
|
--- $uid (document)
|
--- city: "New York"
|
--- borough: "Brooklyn"
|
--- mobNumber: 720555
And in code, it should look like this:
FirebaseFirestore db = FirebaseFirestore.getInstance();
CollectionReference usersRef = db.collection("users");
Query queryByMobNumber = usersRef.whereEqualTo("city", "New York")
.whereEqualTo("borough", "Brooklyn")
.whereEqualTo("mobNumber", 720555);
queryByMobNumber.get().addOnCompleteListener(/* ... /*);
So in Firestore, chaining multiple whereEqualTo calls will work perfectly fine.
Besides that, I see that you are changing a boolean value inside the callback, which will not be seen outside the callback because Firebase API is asynchronous. If you want to learn more about that, I recommend you check this resource. Here is the corresponding repo.
Need to fetch all data rows from my collection("data") with my ID and date range as below
Date start = new Date(01/4/2022);
Date end = new Date(30/4/2022);
fStore.collection("data").whereEqualTo("ID", userId).where("date", ">=",start ).where("date", "<=", end).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
But its complaining using 2 where clauses
solution which helped me is using .whereGreaterThanOrEqualTo("date", "01/5/2022").whereLessThanOrEqualTo("date", "31/5/2022").
I am having trouble getting data from my database.
My database:
My code:
Query query = FirebaseDatabase.getInstance().getReference("Quotes").startAt(5).endAt(10);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
String authorName = data.child("Name").getValue().toString();
String quoteGiven = data.child("Quote").getValue().toString();
name.setText("- " + authorName);
quote.setText(quoteGiven);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this, "Loading Quote failed", Toast.LENGTH_SHORT).show();
}
});
I want to get my data from the 5th child to the 10th child.
I've tried:
Select random entry from Firebase Realtime Database in Java
get random value android firebase java
Firebase queries not working on Android even though the reference retrieves data
However, the is only showing the hard-coded text I left and not the text from the database?
can anyone help me, I am not sure where i went wrong
Try using orderByKey():
FirebaseDatabase.getInstance().getReference("Quotes").orderByKey().startAt(String.valueOf(5)).endAt(String.valueOf(10));
This should give you all the data from the 5th key to the 10th in your database.
From the docs:
orderByKey()
Order results by child keys
https://firebase.google.com/docs/database/android/lists-of-data#sort_data
To solve this, please change the following line of code:
Query query = FirebaseDatabase.getInstance().getReference("Quotes").startAt(5).endAt(10);
to
Query query = FirebaseDatabase.getInstance().getReference("Quotes")
.orderByKey().startAt("5").endAt("10");
The keys that you pass to the startAt() and endAt() methods, should always be strings and not numbers.
I am using Firebase realtime database in my android app. My entries in table is around 300. I'm not able to get the data from the Firebase in Datasnapshot. Sometimes it works after loading 20 minutes. How can I access my data & response fast. It's working well & very fast in iOS with same database & same queries.
private void checkBookingInfo() throws Exception {
mDatabaseReference.child(FireBaseConstants.BOOKING_INFO_TABLE).limitToFirst(10).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot != null) {
countArrival = 0;
countDeparture = 0;
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
//check arrivals date matches with today's date then increment counter
if (snapshot.hasChild(FireBaseConstants.ARRIVAL_DATE)) {
String currentDate = Utils.getCurrentDate();
String arrivalDate = snapshot.child(FireBaseConstants.ARRIVAL_DATE).getValue().toString();
String status = snapshot.child(FireBaseConstants.STATUS).getValue().toString();
if (currentDate.equalsIgnoreCase(arrivalDate) && !status.equalsIgnoreCase("Cancel")) {
countArrival++;
}
}
//check departure date matches with today's date then increment counter
if (snapshot.hasChild(FireBaseConstants.DEPARTURE_DATE)) {
String currentDate = Utils.getCurrentDate();
String departureDate = snapshot.child(FireBaseConstants.DEPARTURE_DATE).getValue().toString();
String status = snapshot.child(FireBaseConstants.STATUS).getValue().toString();
if (currentDate.equalsIgnoreCase(departureDate) && !status.equalsIgnoreCase("Cancel")) {
countDeparture++;
}
}
}
setValueInEditText();
} else {
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("notme", "");
}
});
}
To improve performance of the Firebase query you can add index on the field by which you are ordering Your query. Like
{
"rules": {
"YOUR_NODE": {
".indexOn": ["FIELD1", "FIELD2"]
}
}
}
You can find the helping link here
Firebase also says here
Important: The onDataChange() method is called every time data is
changed at the specified database reference, including changes to
children. To limit the size of your snapshots, attach only at the
highest level needed for watching changes. For example, attaching a
listener to the root of your database is not recommended.
But even if the index is not applied still 20 minutes is much time, you need to check your source code there could be some other issue in the UI, may be data is coming but not populating in the UI.
If we wanna get an object ID we should do this:
String objectId = gameScore.getObjectId();
but what if we wanna get an object ID by a query? Like this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("mytable");
query.whereEqualTo("Title", "Adrians Book");
List<ParseObject> results = null;
try {
results = query.find();
if(!results.isEmpty()) {
String objectId = results.getObjectId();
}
} catch (com.parse4cn1.ParseException e) {
Dialog.show("Err", "Something went wrong.", "OK", null);
}
Sounds interesting don't you think? I wish it could be possible. As you can see in this example the query will get a value from a specific object in the table which could track for the object ID then returning it as well. ParseQuery class should be implemented with getObjectId(). Because by this way applications always could have access to object IDs from the query even after applications get restarted so in the first example the gameScore which is actually an instance of ParseObject would lost reference to the Database after restarting. Getting object IDs by the query it would be able to program applications to get object IDs automatically without the need of doing it manually nor depending on instances of ParseObject.
#Shai Almog: Thank you very much for taking your time to look at the ParseQuery documentation.
I accidentally figured out how to get this done!
ParseQuery<ParseObject> query = ParseQuery.getQuery("mytable");
query.whereEqualTo("Title", "Adrians Book");
List<ParseObject> results = null;
try {
results = query.find();
if(!results.isEmpty()) {
String objectId = results.get(0).getObjectId();
System.out.println(objectId);
}
} catch (com.parse4cn1.ParseException e) {
Dialog.show("Err", "Something went wrong.", "OK", null);
}
Yep, after adding the method .get(index) it allows you to access the method .getObjectId() since results is a list of a ParseObject, then the respective objectId of your query result will be printed in the console! I'm pretty glad it's working because I won't need to serialize each object for now which would be a pain.
Also if you wanna set an instance of ParseObject with an existing objectId in case you need to update something in your Database, you can use this example:
ParseObject po = ParseObject.create("mytable");
po.setObjectId(//YOUR DESIRED OBJECTID HERE, AS LONG AS IT EXISTS IN THE DATABASE);
As far as I know you need to get the whole object then query it's ID. I don't see a query id method here https://github.com/sidiabale/parse4cn1/blob/41fe491699e604fc6de46267479f47bc422d8978/src/com/parse4cn1/ParseQuery.java