I am trying to sync a local PouchDB instance with a remote CouchDB instance on Google App Engine.
I have successfully logged in to the remote instance, but I am getting the following error when I try to sync:
replication paused (e.g. user went offline)
pouchdb-6.3.4.min.js:9 GET https://<ipaddress>:6984/pouchnotes/ net::ERR_CONNECTION_RESET
Sync function
PouchNotesObj.prototype.syncnoteset = function (start, end) {
var start = new Date().getTime();
document.getElementById("syncbutton").innerHTML = "Syncing...";
var i,
that = this,
options = {
doc_ids:['1450853987668']
};
if(start){ options.startkey = start; }
if(end){ options.endkey = end; }
PouchDB.sync(this.dbname, this.remote, { retry: true })
.on('change', function (info) {
console.log('change');
document.getElementById("syncbutton").innerHTML = "Sync Notes";
}).on('paused', function () {
console.log('replication paused (e.g. user went offline)');
document.getElementById("syncbutton").innerHTML = "Sync Notes";
}).on('active', function () {
console.log('replicate resumed (e.g. user went back online)');
document.getElementById("syncbutton").innerHTML = "Sync Notes";
}).on('denied', function (info) {
console.log('a document failed to replicate, e.g. due to permissions');
document.getElementById("syncbutton").innerHTML = "Sync Notes";
}).on('complete', function (info) {
console.log("Sync Complete");
document.getElementById("syncbutton").innerHTML = "Sync Notes";
that.viewnoteset();
that.formobject.reset();
that.show(that.formobject.dataset.show);
that.hide(that.formobject.dataset.hide);
var end = new Date().getTime();
console.log("Time Taken - " + (end - start) + " ms");
}).on('error', function (error) {
console.log("Sync Error:" + JSON.stringify(error));
alert("Sync Error:" + error);
that.showerror(error);
});
}
Edited to add: do I need to set this up?
It turned out that I had not configured the firewall correctly.
For anyone else who stumbles across this issue: you only need SSH tunnelling to access Fauxton on localhost. You don't need it to access the API.
If you want to access the API via https, the port is 6984 (not 5984), and for a non-Google App Engine server, you need something like Nginx set up to provide a SSL certificate. On Google App Engine, SSL certificates are provided.
But you still need to configure CouchDB to enable SSL.
Thanks to the guys at the CouchDB user mailing list for their input.
Related
So we are working on a client application in Windows WPF. We want to include Google as a login option and intend to go straight to the current most secure method. At the moment we have spawned a web browser with the following methods to obtain a Authorization Code
private async void HandleGoogleLogin() {
State.Token = null;
var scopes = new string[] { "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "openid" };
var request = GoogleOAuthRequest.BuildLoopbackRequest(scopes);
var listener = new HttpListener();
listener.Prefixes.Add(request.RedirectUri);
listener.Start();
// note: add a reference to System.Windows.Presentation and a 'using System.Windows.Threading' for this to compile
await Dispatcher.Invoke(async () => {
googleLoginBrowser.Address = request.AuthorizationRequestUri;
});
// here, we'll wait for redirection from our hosted webbrowser
var context = await listener.GetContextAsync();
// browser has navigated to our small http servern answer anything here
string html = string.Format("<html><body></body></html>");
var buffer = Encoding.UTF8.GetBytes(html);
context.Response.ContentLength64 = buffer.Length;
var stream = context.Response.OutputStream;
var responseTask = stream.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
{
stream.Close();
listener.Stop();
});
string error = context.Request.QueryString["error"];
if (error != null)
return;
string state = context.Request.QueryString["state"];
if (state != request.State)
return;
string code = context.Request.QueryString["code"];
await APIController.GoogleLogin(request, code, (success, resultObject) => {
if (!success) {
//Handle all request errors (username already exists, email already exists, etc)
} else {
((App)Application.Current).UserSettings.Email = resultObject["email"].ToString();
((App)Application.Current).SaveSettings();
}
attemptingLogin = false;
});
}
and
public static GoogleOAuthRequest BuildLoopbackRequest(params string[] scopes) {
var request = new GoogleOAuthRequest {
CodeVerifier = RandomDataBase64Url(32),
Scopes = scopes
};
string codeChallenge = Base64UrlEncodeNoPadding(Sha256(request.CodeVerifier));
const string codeChallengeMethod = "S256";
string scope = BuildScopes(scopes);
request.RedirectUri = string.Format("http://{0}:{1}/", IPAddress.Loopback, GetRandomUnusedPort());
request.State = RandomDataBase64Url(32);
request.AuthorizationRequestUri = string.Format("{0}?response_type=code&scope=openid%20profile{6}&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}",
AuthorizationEndpoint,
Uri.EscapeDataString(request.RedirectUri),
ClientId,
request.State,
codeChallenge,
codeChallengeMethod,
scope);
return request;
}
To my understanding, from this point the client app has completed the required portion to have the user login to their google account and approve any additional privileges.
Our API/App server is in GoLang.
APIController.GoogleLogin
from above sends the CodeVerifier and AuthorizationCode to the GoLang application server to then finish off the OAuth2 Flow.
Is this the correct flow given our client-server setup?
If so, what is the best practice for the Go Server to retrieve a Access Token/Refresh Token and get user information? Should the client app be performing a looping check-in to the app server as the app server will not immediately have the required information to login?
Thanks for the help!
How can i detect when a user logs out of firebase (either facebook, google or password) and trigger the onDisconnect method in the firebase presence system. .unauth() is not working. I would like to show a users online and offline status when they login and out, minimize the app (idle) - not just when the power off their device and remove the app from active applications on the device.
I'm using firebase simple login for angularjs/ angularfire
Im using code based off of this tutorial on the firebase site.
https://www.firebase.com/blog/2013-06-17-howto-build-a-presence-system.html
Please i need help with this!
Presence code:
var connectedRef = new Firebase(fb_connections);
var presenceRef = new Firebase(fb_url + 'presence/');
var presenceUserRef = new Firebase(fb_url + 'presence/'+ userID + '/status');
var currentUserPresenceRef = new Firebase(fb_url + 'users/'+ userID + '/status');
connectedRef.on("value", function(isOnline) {
if (isOnline.val()) {
// If we lose our internet connection, we want ourselves removed from the list.
presenceUserRef.onDisconnect().remove();
currentUserPresenceRef.onDisconnect().set("<span class='balanced'>☆</span>");
// Set our initial online status.
presenceUserRef.set("<span class='balanced'>★</span>");
currentUserPresenceRef.set("<span class='balanced'>★</span>");
}
});
Logout function:
var ref = new Firebase(fb_url);
var usersRef = ref.child('users');
service.logout = function(loginData) {
ref.unauth();
//Firebase.goOffline(); //not working
loggedIn = false;
seedUser = {};
clearLoginFromStorage();
saveLoginToStorage();
auth.logout();
};
The onDisconnect() code that you provide, will run automatically on the Firebase servers when the connection to the client is lost. To force the client to disconnect, you can call Firebase.goOffline().
Note that calling unauth() will simply sign the user out from the Firebase connection. It does not disconnect, since there might be data that the user still has access to.
Update
This works for me:
var fb_url = 'https://yours.firebaseio.com/';
var ref = new Firebase(fb_url);
function connect() {
Firebase.goOnline();
ref.authAnonymously(function(error, authData) {
if (!error) {
ref.child(authData.uid).set(true);
ref.child(authData.uid).onDisconnect().remove();
}
});
setTimeout(disconnect, 5000);
}
function disconnect() {
ref.unauth();
Firebase.goOffline();
setTimeout(connect, 5000);
}
connect();
I am building an app for GAE using python API. It is running here. It is a multi-player game. I use the Channel API to communicate game state between players.
But in the app engine the onmessage handler of the channel is not called. The onopen handler is called. onerror or onclose are not called as well. Weird thing is this works perfectly in the local development server.
Is it possible that something like this can work on the development server but not in the app engine itself?
I'll be really really glad if someone can look into following description of my app and help me to figure out what has happened. Thank you.
I looked into this and this questions, but I haven't done those mistakes.
<script>
sendMessage = function(path, opt_param, opt_param2) {
path += '?g=' + state.game_key;
if (opt_param) {
path += '&' + opt_param;
}
if (opt_param2) {
path += '&' + opt_param2;
}
var xhr = new XMLHttpRequest();
xhr.open('POST', path, true);
xhr.send();
};
Above function is used to make a post request to the server.
onOpened = function() {
sendMessage('/resp');
console.log('channel opened');
};
Above is the function I want to be called when the channel is open for the first time. I send a post to the '/resp' address.
onMessage = function(m) {
console.log('message received');
message = JSON.parse(m.data);
//do stuff with message here
};
I want to process the response I get from that request in the above function.
following are onerror and onclose handlers.
onError = function() {
console.log('error occured');
channel = new goog.appengine.Channel('{{ token }}');
socket = channel.open();
};
onClose = function() {
console.log('channel closed');
};
channel = new goog.appengine.Channel('{{ token }}');
socket = channel.open();
socket.onopen = onOpened;
socket.onmessage = onMessage;
socket.onclose = onClose;
socket.onerror = onError;
</script>
This script is at the top of body tag. This works fine in my local development server. But on the app engine,
onOpen function is called.
I can see the request to /resp in the sever logs.
but onMessage is never called. The log 'message received' is not present in the console.
this is the server side.
token = channel.create_channel(user.user_id() + game.user1.user_id() )
url = users.create_logout_url(self.request.uri)
template_values = {
'token' : token,
'id' : pid,
'game_key' : str(game.user1.user_id()),
'url': url
}
path = os.path.join(os.path.dirname(__file__), 'game.html')
self.response.out.write(template.render(path, template_values))
and this is in the request handler for '/resp' request. My application is a multi-player card game. And I want to inform other players that a new player is connected. Even the newly connected player will also get this message.
class Responder(webapp2.RequestHandler):
def post(self):
user = users.get_current_user()
game = OmiGame.get_by_key_name(self.request.get('g'))
if game.user1:
channel.send_message(game.user1.user_id() + game.user1.user_id() , create_message('%s joined.' % user.nickname()))
if game.user2:
channel.send_message(game.user2.user_id() + game.user1.user_id() , create_message('%s joined.' % user.nickname()))
EDIT : user1 is the user who created the game. I want tokens of other players' to be created by adding the user1's user_id and the relevant users user_id. Could something go wrong here?
So when I try this on the local dev server I get these messages perfectly fine. But on the GAE onMessage is not called. This is my app. When the create button is clicked page with above script is loaded and "playernickname connected" should be displayed.
The channel behavior on the dev server and production are somewhat different. On the dev server, the channel client just polls http requests frequently. On production, comet style long polling is used.
I suspect there may be a problem with making the XHR call inside the onOpened handler. In Chrome at least, I see that the next talkgadget GET request used by the channel API is cancelled.
Try calling sendMessage('/resp') outside of the onMessage function. Perhaps enqueue it to get run by using setTimeout so it's called later after you return.
I need to alert the user with the following conditions;
Request timed out
No internet connection
Unable to reach the server
Here's the code; How to capture the following conditions when occurred and alert the user ?
failure: function (response) {
var text = response.responseText;
console.log("FAILED");
},success: function (response) {
var text = response.responseText;
console.log("SUCCESS");
}
I tried the following code to check if the internet is reachable, but it didn't work
var networkState = navigator.network.connection.type
alert(states[networkState]);
if (networkState == Connection.NONE){
alert('No internet ');
};
UPDATE **
I added the following in my index.html, but, when i disable WIFI, i don't see the alert popping.
<script>
function onDeviceReady() {
document.addEventListener("offline", function() {
alert("No internet connection");
}, false);
}
</script>
The best thing to do is to listen to the "offline" event. When you get the offline event you can warn your user and take whatever steps necessary to save data, etc.
For instance, your "deviceready" callback:
document.addEventListener("offline", function() {
alert("No internet connection");
}, false);
This code should work for most all versions of PhoneGap. It's been in since at least the 1.0 release.
Exactly as Simon said, you can use
document.addEventListener("offline", youCallbackFn, false);
or you can interrogate the boolean property
navigator.onLine
(Should return true or false)
However, this technique will tell you whether device is connected. The caveat is such that device can be connected to WiFi, but the router might be offline. In that case, use a polling mechanism, like timely Ext.Ajax.request with lower timeouts. Timeout expired = offline.
You can use PhoneGap's NETWORK API
The network object gives access to the device's cellular and wifi connection information.
You can test it in the following way,
function onDeviceReady() {
navigator.network.isReachable("phonegap.com", reachableCallback, {});
}
// Check network status
//
function reachableCallback(reachability) {
// There is no consistency on the format of reachability
var networkState = reachability.code || reachability;
var states = {};
states[NetworkStatus.NOT_REACHABLE] = 'No network connection';
states[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection';
states[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK] = 'WiFi connection';
alert('Connection type: ' + states[networkState]);
}
You can add 'Ext.device.Connection' in app.js of your application. And check your device is online or offline using code:
if (Ext.device.Connection.isOnline()) {
alert('Connected to internet');
}
else{
alert('You are not connected to internet');
}
Just Embed this in your tag
<body onoffline="alert('PLEASE CHECK YOUR INTERNET SETTING');">
The question duplicates some older questions, but the things may have changed since then.
Is there some official support for connecting to SQL Server from Node.js (e.g. official library from MS)? Or at least some well-maintained third-party library appropriate for a production-grade application?
We usually use ASP.NET MVC/SQL Server combination, but currently I have a task for which express/Node.js seems to be more appropriate (and I'd like to play with something new), so the question is whether we can rely on a Node.js and SQL Server interaction.
UPD: It seems that Microsoft has, at last, released the official driver: https://github.com/WindowsAzure/node-sqlserver
This is mainly for future readers. As the question (at least the title) focuses on "connecting to sql server database from node js", I would like to chip in about "mssql" node module.
At this moment, we have a stable version of Microsoft SQL Server driver for NodeJs ("msnodesql") available here: https://www.npmjs.com/package/msnodesql. While it does a great job of native integration to Microsoft SQL Server database (than any other node module), there are couple of things to note about.
"msnodesql" require a few pre-requisites (like python, VC++, SQL native client etc.) to be installed on the host machine. That makes your "node" app "Windows" dependent. If you are fine with "Windows" based deployment, working with "msnodesql" is the best.
On the other hand, there is another module called "mssql" (available here https://www.npmjs.com/package/mssql) which can work with "tedious" or "msnodesql" based on configuration. While this module may not be as comprehensive as "msnodesql", it pretty much solves most of the needs.
If you would like to start with "mssql", I came across a simple and straight forward video, which explains about connecting to Microsoft SQL Server database using NodeJs here: https://www.youtube.com/watch?v=MLcXfRH1YzE
Source code for the above video is available here: http://techcbt.com/Post/341/Node-js-basic-programming-tutorials-videos/how-to-connect-to-microsoft-sql-server-using-node-js
Just in case, if the above links are not working, I am including the source code here:
var sql = require("mssql");
var dbConfig = {
server: "localhost\\SQL2K14",
database: "SampleDb",
user: "sa",
password: "sql2014",
port: 1433
};
function getEmp() {
var conn = new sql.Connection(dbConfig);
conn.connect().then(function () {
var req = new sql.Request(conn);
req.query("SELECT * FROM emp").then(function (recordset) {
console.log(recordset);
conn.close();
})
.catch(function (err) {
console.log(err);
conn.close();
});
})
.catch(function (err) {
console.log(err);
});
//--> another way
//var req = new sql.Request(conn);
//conn.connect(function (err) {
// if (err) {
// console.log(err);
// return;
// }
// req.query("SELECT * FROM emp", function (err, recordset) {
// if (err) {
// console.log(err);
// }
// else {
// console.log(recordset);
// }
// conn.close();
// });
//});
}
getEmp();
The above code is pretty self explanatory. We define the db connection parameters (in "dbConfig" JS object) and then use "Connection" object to connect to SQL Server. In order to execute a "SELECT" statement, in this case, it uses "Request" object which internally works with "Connection" object. The code explains both flavors of using "promise" and "callback" based executions.
The above source code explains only about connecting to sql server database and executing a SELECT query. You can easily take it to the next level by following documentation of "mssql" node available at: https://www.npmjs.com/package/mssql
UPDATE:
There is a new video which does CRUD operations using pure Node.js REST standard (with Microsoft SQL Server) here: https://www.youtube.com/watch?v=xT2AvjQ7q9E. It is a fantastic video which explains everything from scratch (it has got heck a lot of code and it will not be that pleasing to explain/copy the entire code here)
I am not sure did you see this list of MS SQL Modules for Node JS
Share your experience after using one if possible .
Good Luck
We just released preview driver for Node.JS for SQL Server connectivity. You can find it here:
Introducing the Microsoft Driver for Node.JS for SQL Server.
The driver supports callbacks (here, we're connecting to a local SQL Server instance):
// Query with explicit connection
var sql = require('node-sqlserver');
var conn_str = "Driver={SQL Server Native Client 11.0};Server=(local);Database=AdventureWorks2012;Trusted_Connection={Yes}";
sql.open(conn_str, function (err, conn) {
if (err) {
console.log("Error opening the connection!");
return;
}
conn.queryRaw("SELECT TOP 10 FirstName, LastName FROM Person.Person", function (err, results) {
if (err) {
console.log("Error running query!");
return;
}
for (var i = 0; i < results.rows.length; i++) {
console.log("FirstName: " + results.rows[i][0] + " LastName: " + results.rows[i][1]);
}
});
});
Alternatively, you can use events (here, we're connecting to SQL Azure a.k.a Windows Azure SQL Database):
// Query with streaming
var sql = require('node-sqlserver');
var conn_str = "Driver={SQL Server Native Client 11.0};Server={tcp:servername.database.windows.net,1433};UID={username};PWD={Password1};Encrypt={Yes};Database={databasename}";
var stmt = sql.query(conn_str, "SELECT FirstName, LastName FROM Person.Person ORDER BY LastName OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY");
stmt.on('meta', function (meta) { console.log("We've received the metadata"); });
stmt.on('row', function (idx) { console.log("We've started receiving a row"); });
stmt.on('column', function (idx, data, more) { console.log(idx + ":" + data);});
stmt.on('done', function () { console.log("All done!"); });
stmt.on('error', function (err) { console.log("We had an error :-( " + err); });
If you run into any problems, please file an issue on Github: https://github.com/windowsazure/node-sqlserver/issues
There is a module on npm called mssqlhelper
You can install it to your project by npm i mssqlhelper
Example of connecting and performing a query:
var db = require('./index');
db.config({
host: '192.168.1.100'
,port: 1433
,userName: 'sa'
,password: '123'
,database:'testdb'
});
db.query(
'select #Param1 Param1,#Param2 Param2'
,{
Param1: { type : 'NVarChar', size: 7,value : 'myvalue' }
,Param2: { type : 'Int',value : 321 }
}
,function(res){
if(res.err)throw new Error('database error:'+res.err.msg);
var rows = res.tables[0].rows;
for (var i = 0; i < rows.length; i++) {
console.log(rows[i].getValue(0),rows[i].getValue('Param2'));
}
}
);
You can read more about it here: https://github.com/play175/mssqlhelper
:o)
msnodesql is working out great for me. Here is a sample:
var mssql = require('msnodesql'),
express = require('express'),
app = express(),
nconf = require('nconf')
nconf.env()
.file({ file: 'config.json' });
var conn = nconf.get("SQL_CONN");
var conn_str = "Driver={SQL Server Native Client 11.0};Server=server.name.here;Database=Product;Trusted_Connection={Yes}";
app.get('/api/brands', function(req, res){
var data = [];
var jsonObject = {};
mssql.open(conn_str, function (err, conn) {
if (err) {
console.log("Error opening the connection!");
return;
}
conn.queryRaw("dbo.storedproc", function (err, results) {
if(err) {
console.log(err);
res.send(500, "Cannot retrieve records.");
}
else {
//res.json(results);
for (var i = 0; i < results.rows.length; i++) {
var jsonObject = new Object()
for (var j = 0; j < results.meta.length; j++) {
paramName = results.meta[j].name;
paramValue = results.rows[i][j];
jsonObject[paramName] = paramValue;
}
data.push(jsonObject); //This is a js object we are jsonizing not real json until res.send
}
res.send(data);
}
});
});
});
//start the program
var express = require('express');
var app = express();
app.get('/', function (req, res) {
var sql = require("mssql");
// config for your database
var config = {
user: 'datapullman',
password: 'system',
server: 'localhost',
database: 'chat6'
};
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query("select * From emp", function (err, recordset) {
if (err) console.log(err)
// send records as a response
res.send(recordset);
});
});
});
var server = app.listen(5000, function () {
console.log('Server is running..');
});
//create a table as emp in a database (i have created as chat6)
// programs ends here
//save it as app.js and run as node app.js
//open in you browser as localhost:5000