I am having trouble deciding hot to implement a database for my mobile app. I am using javascript with jquery mobile and phonegap to hopefully deploy to IOS and Android. The database is basically a list of about 60-70 location names, description, latitude and longitude. I need the data to be available even if the user does not have internet access and need to perform queries such as sorting the locations by closest distance.
Is there a way to create the database file beforehand and open as needed or do I need to create the database each time when my app opens? Does the database file reside on the device even after the app is closed or does it create it again when app is restarted?
Any suggestions or examples?
Thanks,
Robert
There are several types of browser storage such as localStorage they are all built in and can be used directly.
Storage objects are a recent addition to the standard. As such they may not be present in all browsers.........The maximum size of data that can be saved is severely restricted by the use of cookies.
Code sample:
function storeMyContact(id) {
var fullname = document.getElementById('fullname').innerHTML;
var phone = document.getElementById('phone').innerHTML;
var email = document.getElementById('email').innerHTML;
localStorage.setItem('mcFull',fullname);
localStorage.setItem('mcPhone',phone);
localStorage.setItem('mcEmail',email);
}
On the other hand, localStorage might not be enough, therefore, external libraries come to hand which actually utilize the browsers built in storage and make the db works cross browsers.
1- SQL like DB sequelsphere (looks like suitable for heavy lifting!)
Code sample for query that will run directly from the browser:
SELECT empl_id, name, age
FROM empl
WHERE age < 30
2- JSON like DB taffydb (looks like suitable for every day activity!)
// Create DB and fill it with records
var friends = TAFFY([
{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active"},
{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active"},
{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active"},
{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active"}
]);
// Find all the friends in Seattle
friends({city:"Seattle, WA"});
3- Since you mentioned mobile, then jstorage is a cross-browser key-value store database to store data locally in the browser - jStorage supports all major browsers, both in desktop (yes - even Internet Explorer 6) and in mobile.
If you would like to have more options ->(client-side-browser-database)
The easiest would be to use localStorage.
window.localStorage.setItem("key", "value");
var value = window.localStorage.getItem("key");
If you need to store more data and have complex queries use a real Database.
Both can be found in the Cordova Docs on Storage
There is also pouch db. I use it with my Ionic App. Works great and very simple to learn and use. I use local storage only for minor temporarily used data (within a session). To persist data even when app is closed and re-opened, Pouchdb works great. By default, it's calls are async. Works well with Promises.
Related
I have a WebApp which sends vía google.script.run.withFailureHanlder(data).withSuccesHandler(data).someFunction(data) some attributes to filter a retrieve data from a spreadsheet in Drive. For example
Host side
google.script.run.withSuccesHandler(e => {
console.log(e);
}).someFunction(data);
Google Apps Server Side:
function someFunction(data){
let book = SpreadsheetApp.openByUrl(url).getSheetByName(data.name);
let info = book.getDataRange().getDisplayValues().filter(x => {
return new Date(data.start) > new Date(x[0]);
});
return result;
}
These spreadsheets are consulted by several people at the same time. At the beginning it was going well but now the data has grown a lot and the queries have become slow due to the amount of data.
Is there any way to optimize these queries without affecting the result of the other people when querying at the same time?
If the data in your spreadsheets does not change frequently, you can try caching the data on the client-side.
You can use IndexedDB as a cache to store the results of common queries in your clients' browsers, assuming their browsers support it. You'll also need to setup some code to periodically check the sheet for changes to update the cache/database on the client-side when necessary.
Dexie is a good IndexedDB wrapper, so I'd recommend using that library to get started.
I usually work on my local eclipse and local IDEs like Sublime Text and use XAMPP locally to work locally. Since local code doesn't involve authentication and many more stuff, I am wondering if its possible to manually inject the session storage values in my web browser so that I can use that in my local settings without having the need to deploy the code to server where I have access to all sessionStorage values I'm looking for.
For example, I have the following code:
var key = JSON.parse(sessionStorage.getItem("loggedInUser"));
var username = key.displayedValues;
console.log("Username retrieved below");
console.log(username);
And whenever I run this code locally, since I don't have any values stored in sessionstorage in my webbrowser, I run into issues. For local testing, I always have to hard code values and test which I don't want.
More clarifications:
I am wondering if I can add it manually in the browser in some manner so that in my code, I can get the value like this sessionStorage.getItem("loggedInUser"). I don't' want to set it first from my code and then access it.
just set it like:
sessionStorage.setItem('loggedInUser', {object details of your user})
i have a big deal with user session monitoring.
I need to kill session after closing last application tab or after browser closing.
So, this work was performed. I have developed small library for working with local storage and session storage and i developed mechanism for monitoring of opened browser tabs.
Just simple object with tab counter.
{
"session_instance_count" : 0
}
And simple methods for writing this object to localstorage:
SessionMonitor.prototype.writeValueByKeyToLS = function (key, value){
var own = this;
own.getLocalStorageInstance().setItem(key, value);
};
SessionMonitor.prototype.getLocalStorageInstance = function () {
return 'localStorage' in window && window['localStorage'];
};
But after deploying another application to Tomcat i have found serious troubles with local storage.
All stored values from first application were available in second application.
I stored some data on http://localhost:8080/app1 this data will be available on http://localhost:8080/app2
App1 sending request to open App2 with some parameters
Note: I do not have access to modify source code of second application.
This is my question:
How to prevent passing HTML5 local storage data between two or more different applications which were deployed at the same container?
Solution with local storage was removed, because it's not provide possibilities for set data separately between applications inside one container with same domain pattern.
I have checked solution with port configuring inside tomcat/conf/server.xml
So we can set different ports to all deployed application. Or we can register one more port for applications
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8086" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8444" />
http://localhost:8080/app2 with http://localhost:8086/app1
Local storages will be unique.
But i can't use this solution, because customer don't want this.
I found one more solution: relation between server side and client side.
Just generating unique window.name and storing it inside server session.
I hope, that it will be helpfull for somebody.
So to start off, I have a raspberry pi, running a lighttp server on arch. I have a webpage that will have a max of 10 people connected at a time. Each user will be given the tag "Master," or "observer." The webpage will have controls that only the "Master," can use.
Just a heads up: I am just learning most of this so I may be making some mistakes about how to accomplish this.
My original idea is has follows. When a user connects to the database their IP address would be grabbed and inserted into a SQLite database, along with a user tag, and time of connection. From there I would be able to query the database for the users tag when they tried to execute various commands.
Whatever I use needs to be very lightweight and not store cookies on the users device.
Here is the JavaScript I currently have, it probably isn't the most efficient, but I plan on getting it working then making it look nice.
This code is supposed to connect the databases and insert the user.
<script type="text/javascript" src="http://l2.io/ip.js?var=myip"></script>
<script type="application/javascript">
var db = openDatabase('userCon.contbl.sqlite', '1.0', 'contbl', 1024);
db.transaction(function(transaction) {
var ip = myip;
var conStatus = "master"
var date = new Date();
console.log('Inserting into the database ' + ip + ',' + conStatus +',' + date);
transaction.executeSql('INSERT INTO contbl(ipAd, conType, lastActive) VALUES (?,?,?,?)',[ip,conStatus,date], function(transaction, results) {
}, function (transaction, err){
console.log(err.message+":Error"); // here an error
});
});
</script>
<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"> </script>
I am unable to connect to the SQLite database I created on the pi, which after my research may be because SQLite is supposed to be run locally and not on a server.
Is there some sort of work around to point to the SQLite database on the pi, or is there a better resource to use for this type of task?
EDIT:
I guess my original post was not specific enough. The basic idea is I need to be able to pass a tiny bit of information from a webpage, back to the server hosting it. i.e. User connect to the server and sends its IP then the server tags that IP as an Observer of Controller. From there the server will treat each person viewing the webpage differently based on how the user was tagged.
My original plan was to use a really light weight database like SQLite, but as I found out, SQLite is local use only. I need to do this on a sever with lower then 10 connections.
My hope is someone has a suggestion, or an example to solve this problem.
The most common way for javascript running on a web page to talk to a server these days is some kind of RESTful web service.
You'll want to find a server-side programming language that runs on the Pi. Maybe node.js? It's like javascript but on a server, see here: http://weworkweplay.com/play/raspberry-pi-nodejs/
You then write whatever methods you want in the server-side language, methods which talk to the database, then have your client-side javascript call those methods. Google "REST services node.js" and you'll find plenty of how-tos.
If the SQLite database is running on the server, and this code runs in the user's browser, it can't connect to the database. The only interaction between the browser and your server is HTTP, unless there's a gigantic security hole in your server.
I'm building a mobile app using OpenUI5 and Cordova. This app consume OData services but must support full offline capabilities. There are many optiones to store data using Cordova such as LocalStorage, Web SQL or even FileWriter. Also I find that OpenUI5 framework offer jQuery.sap.storage to store data through LocalStorage but I can't take this option into account due to the limited storage capacity (5MB).
Is it possible to request the entire data model from the OData service and convert it into JSON model? Because if there is any way to accomplish this, I could write files for every entity in the model (and the metadata file) using the FileWriter and consume this model when the app goes offline.
Does anyone tried to do something like this?
Edited
Thanks for answering...
I'm using jumpifzero tips to set data from the OData services into the Json model, like this:
var sServiceUrl = "http://address:port/DataService.svc/";
var odataModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true);
var jsonModel = new sap.ui.model.json.JSONModel();
odataModel.read("/Dates", {
async: false,
success: function (odata, response) {
jsonModel.setData({ Dates: odata.results });
}
});
this.setModel(jsonModel);
You can also read the odata for each entityset, with the .read method, without any filter. In the success function given to the read, you can put the JS objects in a JSON model.
You can make a layer that fills the JSON model from the odata when online and from localstorage when offline.
You have an option to create offline apps (CRUD) using offline Kapsel plugin (Cordova plugin developed by SAP) that comes with SAP Mobile Platform. You should buy license for SAP Mobile Platform.
You can find more information here: http://scn.sap.com/docs/DOC-58063
I don't suggest offline Kapsel plugin. It is not mature enough to use it and it is actually under development. Furthermore you would need an SMP server for offline feature.
I would rather say you should use a half-baked solution that you form according your needs e.g.: http://coenraets.org/blog/2012/05/simple-offline-data-synchronization-for-mobile-web-and-phonegap-applications/