Simple Firebase Rules about validation - android

I am using firebase database and collecting users with their GPS coordinates and last timestamp from server side. Such as
+users
userId
userLocation
lastTimestamp
Well I want add a firebase Rules which is a user can read only who close to him (for example around the 1 km) and in time (such as people who has been there in for 30 min ). Is that possible to solve in firebase rules segment with newData and validate comments?

Store and retrieve the locations using geofire.
https://github.com/firebase/geofire-java
Setting location data
geoFire.setLocation("userId", new GeoLocation(37.7853889, -122.4056973));
Geo Queries
// creates a new query around [37.7832, -122.4056] with a radius of 0.6 kilometers
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(37.7832, -122.4056), 0.6);
And to add a time limit change the read rule for your specific data.
// only messages from the last 30 minutes can be read
".read": "data.child('timestamp').val() > (now - 18000000)",

I think its in geofire where you set the radius.
I'm also new to firebase so I'm not really familiar with it.
well check this one.
https://github.com/firebase/geofire

Related

How to Retrieve FireStore Users Within a Range With GeoFireStore Android

I am currently working on a program which requires containing location of users with Android Studio. In my users collection, I have location informations as geopoints for each user documents. I need to get all users which are in radius range of a circle. I found GeoFireStore of imperiumlabs -https://github.com/imperiumlabs/GeoFirestore-Android- for this geographic location processes. I can set and get location of a document(single user). But I want to define a center and check if there is/are anyone within the range.
As I understand I need to use geo query event listener as follows;
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {...}
It has Key Entered, Key Moved, Query Ready, Query Error methods, but I couldn't manage what and how to use. I need returned informations of documents(users) which(who) are in my defined range. This way, I can show them main user.
For short words; can someone help me about understanding event listeners of geofirestore?
Thanks for your precious time.
After spending more and more hours I finally solved my issue with
public void onDocumentEntered(DocumentSnapshot documentSnapshot, GeoPoint location) {}
in the GeoQueryDataEventListener Interface. This method works recursively until meeting the requirements of query and I put it in onCreate. I just listed document_id's with documentSnapshot.getId() and tranferred them to an arraylist with mList.add(documentSnapshot.getId()) . Hope this can help someone take care.

Query date range AND time range in firebase

I would like to query my data set for results that occur within a date range and location range (geohash range). I am struggling to find a good solution.
I am using GeoFire and have tried various methods of segrigating my data either by date or location. It's easy enough to build a node for each day and plop geohashes inside but how can i then page through that data without downloading all 5000 results in the city of NYC for example?
If i could sort first on the geohash and then on the date this would be easily achieved but i can not do that in firebase or any NoSQL database.
Someone must have encountered this multirange query problem and i hope you can share what you learned.
Thanks
It's easy enough to build a node for each day and plop geohashes inside but how can i then page through that data without downloading all 5000 results in the city of NYC for example?
Please let me know if I'm misinterpreting your question. Would you be able construct a DatabaseReference to the node representing a specific day, creating a GeoFire object and a GeoQuery, repeating for each day?
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("path/to/dayNode");
GeoFire geoFire = new GeoFire(ref);
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(37.7832, -122.4056), 0.6); // Use this for addGeoQueryEventListener() or something else
// See https://github.com/firebase/geofire-java
This would allow you to only download the locations in the 0.6 km surrounding 37.7832, -122.4056. To prevent downloading too many results at once, start with a small radius and increase from there?
As a side note, I believe Firebase Firestore allows for multiple cursor conditions such as:
db.collection("locations")
.orderBy("locationhash")
.orderBy("date")
.startAt(locationHash, startDate)
.limit(25);
Unfortunately, I don't think you would be able to specify a radius while sorting by date and paginating unless you extended the work done in GeoFire or GeoFirestore. Hopefully someone else has a better idea.

Retrieving data from firebase to google maps

I am making an app which downloads LatLngs from firebase and shows them as markers in google maps API, users can add new LatLngs.
In my database I also have the pricepoint and types of markers. In the main screen the user can choose what types of marker he wants to see on the map.
So my application does something like this:
locations.orderByChild(pricepoint).equalTo(choosenPricepoint);
and then I check programmatically if types match those chosen by the user
int type = Integer.parseInt(locations.child("restaurantType").getValue().toString();
if(type == funCode|| type == runingCode|| type == sportsCode
{
mMap.addMarker(new MarkerOptions().position(snapshot.getLatlng);
}
And it works fine with 250 records, but I'm expecting over 10,000 of them in my database so I am worried that it will be too slow.
I don't know if showing markers only where user's maps camera is and deleting other will be faster. What do you suggest?
You can use GeoFire , a firebase library that uses GeoHashes to merge lat+lon into a single property.That way you can do the distance filtering directly on the database.
You should have 2 entries in firebase database,one for setting your object location and one for setting your object with its fields.
As you can see they have the same id.So first you are queriing for nearby object by GeoFire in geo_data entry,and you will get the ids of the object which are nearby,then you can retreive object with its properties directly from database using the ids in my case in user_data entry

Search in Firebase based on distance

I'm migrating an application that was using Mysql to firebase, and I managed to migrate it almost all, just missing the part of search, I did not quite understand how it works. I'm trying to do this query below in firebase.
SELECT *, (6371 * acos( cos(radians(?)) * cos(radians(latitude)) * cos(radians(?) - radians(longitude)) + sin(radians(?)) * sin(radians(latitude)) )) AS distance FROM usuario ORDER BY distance
What I'm trying to do is pass the latitude and longitude of my User to firebase and he returns me all users ordering the nearest to the farthest.
Note: This is not the same query that I use in my application, that I just find on google and do not know if this work, but you can get an idea of what I'm trying to do.
Note ²: English is not my native language :P
The example SQL query you provided uses a capability of SQL that does not exist in Firebase: the ability to calculate an expression using the column values for each row in the table and then use the value of that expression to filter and sort the query result.
I don't see a way to use Firebase to perform the type of query you want.
You might want to take look at the Geofire library. I have not used it and its capabilities seem to be related to proximity filtering, not the sort-by-distance feature you need, but maybe you can adjust your requirements to make use of its features.
I concur with Qbix and would normally post this as a comment, but I want to make sure the Geohash comment doesn't get lost in the small-text shuffle.
GeoFire uses Geohash codes to create its keys and allow range-matching. For basic apps this may be fine, but the second you go beyond the US this creates a lot of trouble because it doesn't work well around the equator and Prime Meridian (UK). See the Wikipedia Page on Geohash for details, specifically: Edge case locations close to each other but on opposite sides of the 180 degree meridian will result in Geohash codes with no common prefix (different longitudes for near physical locations)..
Firebase is an amazing product, but not a one-size-fits-all tool. If you need good Geo-based search/matching, use a tool like ElasticSearch, MySQL, Algolia, etc. that support it directly. Reducing the number of components in cases like this doesn't decrease complexity, it increases it.
You can use Geofirestore library
https://github.com/geofirestore/geofirestore-js
here is the example used:
import * as firebase from 'firebase/app';
import 'firebase/firestore';
import { GeoCollectionReference, GeoFirestore, GeoQuery, GeoQuerySnapshot } from 'geofirestore';
// Initialize the Firebase SDK
firebase.initializeApp({
// ...
});
// Create a Firestore reference
const firestore = firebase.firestore();
// Create a GeoFirestore reference
const geofirestore: GeoFirestore = new GeoFirestore(firestore);
// Create a GeoCollection reference
const geocollection: GeoCollectionReference = geofirestore.collection('restaurants');
// Create a GeoQuery based on a location
const query: GeoQuery = geocollection.near({ center: new firebase.firestore.GeoPoint(40.7589, -73.9851), radius: 1000 });
// Get query (as Promise)
query.get().then((value: GeoQuerySnapshot) => {
console.log(value.docs); // All docs returned by GeoQuery
});
where {1000} in the query is the radius of location search

ParseGeoLocation query

I'm currently making a android app but I ran into a bit of an issue, I'm using Parse.com as my server and I'm trying to use their ParseGeoLocation to get the current users location and compare it to the other users location using their ParseQuery.
And by this i mean (Get current user location) > (Send to server object in column "location") > (Check if within other users location) > (Return other users name/data if true)
I've been trying to do this correctly for the last few days but to no avail.
Does anyone know how to do this? I've been searching the web but not really finding the right things. I've tried on their site "Docs" but wasn't really helpful.
You can use the query whereNear constrain. You will provide your user location and call find method. This will return an array of objects ordered by distance (nearest to farthest) from your provided user location. One example code can be given as follows;
ParseGeoPoint userLocation = //current user location
ParseQuery<ParseObject> query = ParseQuery.getQuery("LocationStoredTableName");
query.whereNear("location", userLocation);
query.limit(10); //10 objects will return
query.findInBackground(new FindCallback<ParseObject>() { ... });
Hope this helps.
Regards.

Categories

Resources