Reputation: 1861
I am trying to implement a node.js server with firebase as my persistent layer.
Users can log in and get an accessToken that is generated from the custome authentication firebase module.
Then on each future request the clients will give the server their given accessToken and then the server will perform actions by connecting to a the firebase ref as the requesting user.
var ref = new Firebase("https://cexample.firebaseio.com/");
ref.authWithCustomToken(token, function(error, authData) {
ref.child("users").child(authData.uid).set({
data: authData.uid,
provider: "custom"
});
});
this approach doesn't work since firebase maintains only once authentication state for a given firebase url.
this means that performing this code:
var ref = new Firebase("https://cexample.firebaseio.com/");
ref.authWithCustomToken(token1, function(error, authData) {
ref.child("users").child(authData.uid).set({
data: authData.uid,
provider: "custom"
});
});
var ref1 = new Firebase("https://cexample.firebaseio.com/");
ref1.authWithCustomToken(token2, function(error, authData) {
ref.child("users").child(authData.uid).set({
data: authData.uid,
provider: "custom"
});
});
will not work. only the second callback, the one of ref1, will be called.
Is there anyway to be able to handle requests to firebase from a node.js server as different users per request?
Upvotes: 1
Views: 993
Reputation: 1659
You could spawn a child process for each separate auth token you want to use, but that would not be very efficient:
// server.js
for (var i in users) {
var user = users[i];
var token = createTokenForUser(user);
child_process.spawn("./single-user-worker.js", [token]);
}
// single-user-worker.js
var token = process.argv.pop();
var ref = new Firebase("https://cexample.firebaseio.com/");
ref.authWithCustomToken(token, ...);
It would be more efficient to just create a high-privileged token for the server to use for all users:
var token = createAdminToken();
var ref = new Firebase("https://cexample.firebaseio.com/");
ref.authWithCustomToken(token, function(error, authData) {
for (var i in users) {
var user = users[i];
ref.child("users").child(user.uid).set({
data: user.uid,
provider: "custom"
});
}
});
Is the node.js server serving web pages? Can the clients contact Firebase directly? Sending the custom token to the client for its own use would be a more normal workflow:
function (request, response) {
var token = createTokenForUser(request.user);
var script = ['<script>',
'var token='+JSON.stringify(token)+';',
'var ref= new Firebase(...);',
'ref.authWithCustomToken(token, ...);',
'</script>'].join("\n");
response.end(script);
}
If you are really not interested in doing things the usual way, you can just use standard node tools like request to make calls to the Firebase REST API with your custom token in the auth
query parameter, like so:
var request = require("request");
var token = createTokenForUser(...);
var uid = ...;
request({
method: "POST",
url: "https://cexample.firebaseio.com/users/"+uid,
qs: {auth: token},
body: {
data: uid,
provider: "custom"
},
json: true
});
Without the standard Firebase library it will be hard to react to changes. You will need to set the header Accept: text/event-stream
and write handlers for "data"
events and make sure to close connections when you are done with them so you don't run up your Firebase bill.
Upvotes: 2