Ionic 2 data reload when network isn't present - javascript

I just want to know if this is possible and how it could be done.
Let's say an Android user has a network connection and makes a change that then updates the database. Then the user loses network connection but still makes changes on their device. They can't obviously send data to the database without a connection.
But when they receive a connection again, the changes they made when there wasn't a connection are automatically updated and sent to the database. How would I go about doing such a thing with Ionic 2 framework? Please point me in the right direction.
Thanks!

Yes it's possible.
For that you need SQLite. It is best to make a SQLite service.
In the first phase the most important thing is to save data to offline/local database. In this case this is SQlite.
When there is no network connection and user make some action save data to table created in your SQlite database.
finishFunction(){
if(this._connectivityService.isOnline()){
//Send data directly to external database
this._api.sendData(this.parameters).subscribe(res => {
});
} else {
//Store data in offline SQLite database
this._database.myOfflineTable(this.parameters);
}
}
After that, in app home page check when network connection is available and call function that sends local/offline data through API to external database. When API return success message you can empty offline table.
sendMyOfflineData(){
this._database.getOfflineTable().then((result) => {
this.OfflineTableList = <Array<Object>> result;
if(this.OfflineTable.length != 0){
for(var i = 0; i < this.OfflineTable.length; i++){
this._api.sendData(this.OfflineTable[i]).subscribe(res => {
if(res.status == true){
this._database.deleteOfflineTable();
}
});
}}
}, (error) => {
console.log("ERROR: ", error);
});
}
If you need more details, I'm here.

Related

PouchDB remote authentication password storage in browser

I'm playing around with in browser pouchdb and couchdb and and remote sync. This was all straight forward but now I'm at a roadblock that I'm not able to figure out myself.
For security reasons every user of the website has its own datbase that is only accessable via the respective couchdb user.
const localDB = new PouchDB('test');
const remoteDB = new PouchDB(process.env.REMOTE_DATABASE);
const username = process.env.REMOTE_USER;
const password = process.env.REMOTE_PASSWORD;
remoteDB.login(username, password, (error, response) => {
if (error) {
console.error('Login failure', error)
} else {
console.log('Login success');
dispatch('sync');
}
});
console.log('sync');
localDB.sync(remoteDB, {live: true})
.on('change', response => {
console.log(response);
})
.on('error', error => {
console.error('Sync failure', error);
});
To create a user I need a backend layer to handle user registration and creation. THis is now problem sind i can store the admin credentials "secure" on the server. Now my problem is how to handle the pouchdb user credentials in the browser. It would be possible to ask for the credentials on the first loading of the app and then storing it in the ram but this would lead to logging in on each reload of the page. Is there any way to use like cookie/token auth?
Or is there a way to proxy the pouchdb connection through a backend proxy that handles the authentication!?
Any tips would be appreciated.
The simplest way to use cookie authentication is by using the pouchdb-authentication plugin on GitHub. If you do not want to use this then you should read this previous question (#23986912) on Stackoverflow which discusses this in more detail.
Hope this helps.

PouchDB and React-Native not replicating .to() but .from() is working

For some reason documents created on my app are not showing up on my remote couchdb database.
I am using the following
import PouchDB from 'pouchdb-react-native'
let company_id = await AsyncStorage.getItem('company_id');
let device_db = new PouchDB(company_id, {auto_compaction: true});
let remote_db = new PouchDB('https://'+API_KEY+'#'+SERVER+'/'+company_id, {ajax: {timeout: 180000}});
device_db.replicate.to(remote_db).then((resp) => {
console.log(JSON.stringify(resp));
console.log("Device to Remote Server - Success");
return resp;
}, (error) => {
console.log("Device to Remote Server - Error");
return false;
});
I get a successful response the response:
{
"ok":true,
"start_time":"2018-05-17T15:19:05.179Z",
"docs_read":0,
"docs_written":0,
"doc_write_failures":0,
"errors":[
],
"last_seq":355,
"status":"complete",
"end_time":"2018-05-17T15:19:05.555Z"
}
When I go to my remote database, document_id's that am able to search and grab on the application do not show up.
Is there something I am not taking into account?
Is there anything I can do to check why this might be happening?
This worked when I used the same scripting method in Ionic and when I switched to React-Native I noticed this is the case.
NOTE: When I do .from() and get data from remote to the device, I get the data. For some reason it just isn't pushing data out
"Is there anything I can do to check why this might be happening?"
I would try switching on debugging as outlined here.
PouchDB.debug.enable('*');
This should allow you to view debug messages in your browser's JavaScript console.

how to wait until localStorage.setItem finishes in angular 4

i am developing an angular 4 application. once the user wants to log in to the system it sends a http request to the server and server validate the user and it sends a reposnce with a authentication key and other user details. i use local storage to save these information
login() {
if (this.loginForm.valid) {
this.serviceUserService.authenticate(this.loginForm).subscribe(response => {
if (response.message != "_err") {
//saving the current user in localstorage
localStorage.setItem('currentUser', JSON.stringify(response.body));
this.router.navigateByUrl('/');
} else {
alert("invalid login. Please try again")
}
}, err => {
console.log(err);
})
}
}
it seems like that localStorage.setItem() is an asynchronous function. so before it save the curent user in the local storage it redirect to the main page. but since the token is not saved in the local storage no http requests will work. how do i wait until localStorage.setItem() finish it's task and then send the user to home page.
You are wrong , all localStorage calls are synchronous. Probably you can add a check before navigating to the next page.
localStorage.setItem('currentUser', JSON.stringify(response.body));
this.router.navigateByUrl('/');
In case anyone is getting the same kind of a issue... the reason for this was I have created a variable in my service class to save the current user and set the value for that variable inside the constructor. So, in the login page when the authenticate method gets called it tries to initialize the variable but since user is not logged in yet it is still null. That was causing the issue.

Node.js - Redis - PHP : refresh and quit between browsers close the wrong room

I'm new to stakoverflow, but I swear that I really searched a lot before ask here. In short, I've two browsers opened, and two PHP sessions, redis takes care of the session, but when I try to refresh the page the online user that refreshed the node.js server take the (maybe socket id?) of the refreshed one, and if I do a logout on the not refreshed one, the connection will close as the refreshed one.
I know, it's messy. I have to set a socket id array with also session together?
Currently, I am storing each new connection in a room (to have private sockets), but I become to think that maybe I've to change something for make all work properly.
How you handle a refreshed page? Also because can happen that a user open another tab of same website, or a friend give a link and you visit that link, and you need the session id (ok) the saved user (ok) and the socket io socket (wrong in my case?). Maybe its because I don't know how to get the cookie outside this:
socket.on('connection', function(client) {
cookieManager = new co.cookie(client.request.headers.cookie);
clientSession.get("sessions/"+cookieManager.get("PHPSESSID"), function(error, result) {
if (error) {
console.log("error : "+error);
}
if (result != "") {
// if (result.toString() != "") {
console.log("PHP session id: " + cookieManager.get("PHPSESSID"));
//console.log(result.toString());
//console.log("print result: " + result); //warning! this will parse entire session, test only!
userData = JSON.parse(result);
}
}
}
By default, the nodejs server does not send back the php cookie.
When I used php + redis + socket.io, i used the configuration present in this answer: here (edit: I used memcache & a custom class, now I use redis + publish/subscribe to broadcast events!)
to connect, i read the cookie with javascript from the page and sent it in the beginning of the connection.
/** C "cookie" function, gets the cookie string.
* #param {string} [k] - key, the cookie to get
*/
function C(k){return(document.cookie.match('(^|; )'+k+'=([^;]*)')||0)[2]}
s = io.connect("//io."+ window.location.host +"/", {query: "id=" + C('PHPSESSID')});
from the nodejs side:
io.sockets.on("connection", function (socket) {
var cookie = socket.handshake.query.id;
...
});
I stored the data formatted in json in the redis database, with phpsessid as key.
Hope it helps!

Stay Connected to Socket.io while switching pages

I have a phonegap app in which i connect to my node.js socket like so:
var socket = io.connect('http://54.213.92.113:8080');
It works fine but when I go to a different page, the socket gets disconnected.
I could just write the same code in the javascript on the next page but that's messier than I think it needs to be - as it would open up a new connection when it could have just stayed connected in the first place.
Is there any way to stay connected to the socket even if I switch pages?
suppose you have a multi-page application then ,here you can do a trick that when your socket gets connected first time when the page loads then you can assign the session id to that particular connection like this.and then bind that connection to that session.
io.on('connection', function(socket) {
socket.on('start-session', function(data) {
console.log("============start-session event================")
console.log(data)
if (data.sessionId == null) {
var session_id = uuidv4(); //generating the sessions_id and then binding that socket to that sessions
socket.room = session_id;
socket.join(socket.room, function(res) {
console.log("joined successfully ")
socket.emit("set-session-acknowledgement", { sessionId: session_id })
} else {
socket.room = data.sessionId; //this time using the same session
socket.join(socket.room, function(res) {
console.log("joined successfully ")
socket.emit("set-session-acknowledgement", { sessionId: data.sessionId })
})
}
});
Now you had binded the socket connection to a session now you are sending an acknowledgement too at the client side also .There what you can do is that store the session id to the web browsers session storage like this
At client side code
socket.on("set-session-acknowledgement", function(data) {
sessionStorage.setItem('sessionId', data.sessionId);
})
This will store the session id in the browsers session storage.Now when the page is navigated from page1 to page2 and so on. then send that session id to the server so that you will be connected to the same session logically like this
var session_id;
// Get saved data from sessionStorage
let data = sessionStorage.getItem('sessionId');
console.log(data)
if (data == null) {
session_id = null//when we connect first time
socket.emit('start-session', { sessionId: session_id })
} else {
session_id = data//when we connect n times
socket.emit('start-session', { sessionId: session_id })
}
So basically the logic behind is that we can use same session for multiple socket connections by doing this as every time the socket will be joined to that particular room only and emit the events which you can listen on server side and vice a versa.
Only if you build it as a single page application where the actual page doesn't reload load when navigating. However it would probably be better to design your socket.io code and your server side to be resilient to frequent socket connect / disconnect. This is especially true for code written to run on a cell phone.

Categories

Resources