Change Geofire firebase structure with ionic [duplicate] - javascript

I am storing location data via GeoFire in my database, here is the structure:
geofire
-Ke1uhoT3gpHR_VsehIv
-Kdrel2Z_xWI280XNfGg
-g: "dr5regw90s"
-l
-0: 40.7127837
-1: -74.00594130000002
It is avised to store a location's information and geofire data in separate nodes, however I see an advantage to storing some extra data under these geofire nodes, such as the name of a business. This way I'd only have to make only one call to my Firebase to fetch nearby locations as well as their names.
Is this achievable via the key_entered method? Has anyone created a similar solution? Is this truly that bad of an idea even if the location info is consistently updated?
Any input is appreciated!

Firstly the structure you are using for the app is wrong.
let us take an example of users app
When you use Geofire, you have two lists of data:
a list of user details for each user
a list of latitude and longitude coordinates for each user
You are trying to store both in same structure like this
"users" : {
<userId> : {
"userData" : "userData",
<geofireData>
...
}
}
Trying to store userdata and geofiredata in one node is a bad idea, since you're mixing mostly static data (the properties of your user) with highly volatile data (the geo-location information).Separating the two out leads to better performance, which is why Geofire enforces it.
This is why when you try to add geolocation data to a user node it overwrites previous user details for that node.
Your database structure should be like this.
"Users" : {
<UserId> : {
"UserData" : "UserData",
...
}
}
"Users_location" : {
<UserId> : {
<geofireData> ...
}
}
Hence for the same user Id you create 2 structures one for user details and another for geolocation details of that user.
How to push the user and set the geofire data.
String userId = ref.child("users").push().getKey();
ref.child("users").child(userId).setValue(user);
geoFire = new GeoFire(ref.child("user_location"));
geoFire.setLocation(userId, new GeoLocation(lattitude, longitude));
the userId you use in geolocation is same as the one you got during push().
Hence for each userId you have userdetails in one structure and location details in anotehr structure.
To get the data, first you need to do GeoQuery at users_location node and then get the data on the onKeyEntered method. The parameter key is userId from my example.
geoFire=newGeoFire(FirebaseDatabase.getInstance().getReference().child("users_location");
geoQuery = geoFire.queryAtLocation(geoLocation), radius);
geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
#Override
public void onKeyEntered(String key, GeoLocation location) {
//retrieve data
//use this key which is userId to fetch user details from user details structure
}
};
Happy coding :)

It might be late but just in case someone else is facing the same issue.
It's very possible to integrate and manipulate GeoFire data with existing data.
The main challenge faced by many developers is the fact that they can't update the GeoFire geolocation without deleting the existing data using geoFire.setLocation("id", location); as reported in this issue geofire-java/issues/134.
This is my solution for that.
1. Setting mixed data with GeoFire on FireBase
Let's consider below Structure:
|-userExtra :
|-userId1 :
|- userId : "userId1",
|- userName : "Name1",
|- <geofireData> (i and g)
|...
|-userId2 :
|- userId : "userId2",
|- userName : "Name2",
|- <geofireData> (i and g)
|...
You can generate the geoHash with GeoHash geoHash = new GeoHash(location) and set the value to the child directly in the firebase.
/*Java Code*/
void setGeoFireMixData(UserExtra user, Location location){
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref = ref.child("users").child(user.userId);
//Setting userData if needed
ref.child("userId").setValue(user.id);
ref.child("Name").setValue(user.name);
// .... other references
//Setting GeoFire Data
GeoHash geoHash = new GeoHash(location);
ref.child("l").setValue(Arrays.asList(location.latitude, location.longitude));
ref.child("g").setValue(geoHash.getGeoHashString());
}
2. Fetching mixed data with GeoFire
About the question:
Is this achievable via the key_entered method? Has anyone created a similar solution? Is this truly that bad of an idea even if the location info is consistently updated?
I'd say, you can't retrieve both extra data and GeoFire using only the GeoQueryEventListener with onKeyEntered. You will need to use GeoQueryDataEventListener. For that, you can define the PoJo of your data considering the structure defined above.
...
GeoQueryDataEventListener geoQueryDataEventListener = new GeoQueryDataEventListener() {
#Override
public void onDataEntered(DataSnapshot dataSnapshot, GeoLocation location) {
UserExtra user = dataSnapshot.getValue(UserExtra.class);
actionOnUser(user);
}
...
};
...
geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude,longitude), 0.5);
geoQuery.addGeoQueryDataEventListener(geoQueryDataEventListener);
...
The class UserExtra can be defined as below:
public class UserExtra implements Serializable {
String userId;
String name;
...
List<Double> l; //GeoLocation
String g;
}
That will give you all the data in your node including the geoFire data.

I had this solution I am using now for Javascript:
Save any extra info with key separated by symbol i.e. underscore
Make sure auth id is in the key, which is used in security rules to ensure only the user can write to their node
"rules": {
"geofire": {
".read":"true",
"$extrainformation_authid":{
".write":"$extrainformation_authid.contains(auth.uid)"
}
}
}
Client-side, separate the information by the underscore

Related

Accessing Data in a relationship from another entity in a powerapp component

I have a one-to-many relationship between the accounts entity and a custom entity called clients where an account can have many clients. I am developing a powerapp component that I want to display details about the latest added client on the accounts main form.
What I’d like to know is how I would identify the account being viewed (as in get the relationship identifier) and retrieve the related data from the client entity.
Is this possible?
If I understand your relationship it is 1(Account)-->N (clients).
so based on this, on your every client record you will have a lookup filed (relationship) filed which will look up to Account Record.
below is an example for Javascript but this will give you understanding of data structure and relationship
Example: get all contacts for a Parent Account
// NOTE: retrieveMultipleRecords is available in offline mode, if you need this functionality change the call to Xrm.WebApi.offline.retrieveMultipleRecords
// https://learn.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/reference/xrm-webapi/offline
Xrm.WebApi.online.retrieveMultipleRecords("contact", "?$select=contactid,_parentcustomerid_value,fullname&$filter=_parentcustomerid_value eq 7b649f5c-c986-e411-a2ea-00505693000c").then(
function success(results) {
console.log(results);
for (var i = 0; i < results.entities.length; i++) {
var result = results.entities[i];
// Columns
var contactid = result["contactid"]; // Guid
var parentcustomerid = result["_parentcustomerid_value"]; // Customer
var parentcustomerid_formatted = result["_parentcustomerid_value#OData.Community.Display.V1.FormattedValue"];
var parentcustomerid_lookuplogicalname = result["_parentcustomerid_value#Microsoft.Dynamics.CRM.lookuplogicalname"];
var fullname = result["fullname"]; // Text
}
},
function(error) {
console.log(error.message);
}
);

How to retrieve data from firebase using the key value

I am working on a web application and I purely used javascript to store read and delete data. So it's a blog-type application in which I currently am working on, and my database schema is like the following picture.
Now the problem is I want to retrieve values of posts (like description, imageurl, task) by key value postCategory which is "software engineering".
You need to use the equalTo
postsRef.orderByChild("postCategory").equalTo("software engineering").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
System.out.println(dataSnapshot.getKey());
}
// ...
});

Question about Model in MVC architecture in web app using NodeJs and MySQL

I am new to NodeJs and I am trying to create a web application using express framework and MySql. I get that in MVC architecture the views are for example the *.ejs files. The controllers are supposed to have the logic and the models should focus on the database.
But still I am not quite sure what is supposed to be inside the model. I have the following code in my controller (probably wrong, not following mvc design):
const mysql = require('mysql');
const db = mysql.createConnection(config);
db.query(query, (err, result) => {
if (err) {
return res.redirect('/');
}
res.render('index.ejs', {
users: result
});
});
Now from what I've read the controller should ask the model to execute the query to the database, get the results and render the view (index.ejs').
My question is this: What should be inside the model.js file? Can I make something like this?
controller.js
const db = require('./models/model.js');
db.connect();
const results = db.query(query);
if(results != null) {
res.render('index.ejs'){
users: result
});
}
model.js will make a query to mysql handle any errors and return the result.
From what I've read I have two options. Option1: pass callback function to model and let the model render the view (I think that's wrong, model should not communicate with view, or not?) Option2: possible use of async/await and wait for model to return the results but I am not sure if this is possible or how.
The model is the programmatic representation of the data stored in the database. Say I have an employees table with the following schema:
name: string
age: number
company: company_foreign_key
And another table called companies
name: string
address: string
I therefore have two models: Company and Employee.
The model's purpose is to load database data and provide a convenient programmatic interface to access and act upon this data
So, my controller might look like this:
var db = require('mongo');
var employeeName = "bob";
db.connect(function(err, connection){
const Employee = require('./models/Employee.js'); // get model class
let employeeModel = new Employee(connection); // instantiate object of model class
employee.getByName(employeeName, function(err, result){ // convenience method getByName
employee.getEmployeeCompany(result, function(err, companyResult){ // convenience method getEmployeeCompany
if(companyResultl) { // Controller now uses the results from model and passes those results to a view
res.render('index.ejs')
company: companyResult
});
})
})
}
})
Basically, the model provides a convenient interface to the raw data in the database. The model executes the queries underneath, and provides convenient methods as a public interface for the controller to access. E.g., the employee model, given an employee object, can find the employee's company by executing that query.
The above is just an example and, given more thought, a better interface could be thought up. In fact, Mongoose provides a great example of how to set up model interfaces. If you look at how Mongoose works, you can use the same principles and apply them to your custom model implementation.

Firebase Database retrieve unrelated nodes

I'm using Firebase framework to create a WepApp for a Final project that I'm doing. I'm managing small air-line company. I have the database structure below:
{
destination:
{New-York:
{
1:{
person1:"ADAM",
person2:"Joy"}
2...31:
}
Los-Angeles:{
1:{
preson1:"Roy",
person2:"Noy"
}
2..31:
}
}
How can I retrieve only person1 from New-York[1] and Person2 from Los-Angeles[5]? Is it possible? Or anyone else have an other solution the wont kill my Bandwidth credits? Thanks a lot.
**EDIT: I'm using it for a Web App hence I'm writing the code with JavaScript (Using Web-storm IDE).
I tried pulling the whole database , meaning retrieving the whole 'destination' object using:
var ref=firebase.database().ref('/destination/').once("value");
ref.then(function(snapshot){MY-CODE...})
but doing that I'm "eating" my bandwidth allocating
If you want to retrieve the value stored in person1 or person2, then just specify the full path and then call snapshot.val(), it will return the value stored in that location.
firebase.database().ref('destination/New-York/1/person1').on('value', function(snapshot) {
console.log(snapshot.val()); //ADAM
});
firebase.database().ref('destination/Los-Angeles/5/person2').on('value', function(snapshot) {
console.log(snapshot.val()); //Name of Person 2
});

Filtering and only display certain information using Web API

I am developing a website that is mostly written in asp.net and Javascript and I am using a lot of ajax on it to retreive and display information from a SQL database.
To perform all these operations I am using Web API as the communication path to perform server related tasks.
There are quite a few places on my website I will only want to display certain information. For example, I have the following route of which I may consume: api/customers/orders/order/5
This would retreive data for Order #5. However, what if some places on my website only need to display the Order # or Order Description or something? and what happens if I want to filter the database a bit more, to perhaps only display orders with specific information. By using the above URL it would return everything about the order to the web browser and seems a bit unnecessary.
If I have several needs for different filters then I don't understand how the routing would work for as some bits would be optional.
Any recommendations would be greatly appreciated! Or perhaps i'm missing something!
Thanks
You can do something like following. You can create request filter like specified in below link.
public class RequestFilterAttribute : Attribute, IHasRequestFilter
{
#region IHasRequestFilter Members
public IHasRequestFilter Copy()
{
return this;
}
public int Priority
{
get { return -100; }
}
public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto)
{
var query = req.QueryString["q"] ?? req.QueryString["query"];
var limit = req.QueryString["limit"];
var offset = req.QueryString["offset"];
var user = requestDto as QueryBase;
if (user == null) { return; }
user.Query = query;
user.Limit = limit.IsEmpty() ? int.MaxValue : int.Parse(limit);
user.Offset = offset.IsEmpty() ? 0 : int.Parse(offset);
}
#endregion
}
.Net WebAPI URI convention for advanced searching /filtering

Categories

Resources