diff options
Diffstat (limited to 'firebase-io')
-rw-r--r-- | firebase-io/.gitignore | 1 | ||||
-rwxr-xr-x | firebase-io/firebase-io.js | 134 | ||||
-rw-r--r-- | firebase-io/package.json | 23 |
3 files changed, 158 insertions, 0 deletions
diff --git a/firebase-io/.gitignore b/firebase-io/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/firebase-io/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/firebase-io/firebase-io.js b/firebase-io/firebase-io.js new file mode 100755 index 0000000..8a94076 --- /dev/null +++ b/firebase-io/firebase-io.js @@ -0,0 +1,134 @@ +#!/usr/bin/env node +const firebase=require("firebase-admin"); +const util=require("util"); + +firebase.initializeApp({ + credential:firebase.credential.cert(require("./firebaseServiceAccountKey.json")), + databaseURL:"https://tomsg-83196.firebaseio.com", +}); + +const fieldConverters=new Map([ + ["token",(b)=>b.toString()], + ["user",(b)=>b.toString()], + ["room",(b)=>b.toString()], + ["message",(b)=>b.toString()], + ["timestamp",(b)=>b.toString()], // Nanosecond timestamps are too close to 52-bit range + ["online",(b)=>parseInt(b.toString(),10)], +]); + +function typeConvertFields(fields){ + for(const key of fields.keys()){ + const conv=fieldConverters.get(key); + if(conv!=undefined)fields.set(key,conv(fields.get(key))); + } +} + +function readFields(buffer){ + const fields=new Map(); + if(buffer.length==0)return fields; + let cursor=0; + while(true){ + let idx=buffer.indexOf(32,cursor); + if(idx==-1){ + console.error("ERR: Incomplete field in input line"); + return null; + } + const key=String(buffer.slice(cursor,idx)); + cursor=idx+1; + + idx=buffer.indexOf(32,cursor); + if(idx==-1){ + console.error("ERR: Incomplete field in input line"); + return null; + } + const arglen=parseInt(String(buffer.slice(cursor,idx)),10); + if(arglen<0||arglen==null||isNaN(arglen)){ + console.error("ERR: Invalid length in input line"); + return null; + } + cursor=idx+1; + + if(cursor+arglen>buffer.length){ + console.error("ERR: Length larger than remaining line in input line"); + return null; + } + const arg=buffer.slice(cursor,cursor+arglen); + cursor+=arglen; + + fields.set(key,arg); + + if(cursor==buffer.length)break; + if(buffer[cursor]!=32){ + console.error("ERR: No space after argument in input line"); + return null; + } + cursor++; + } + return fields; +} + +function processMessage(type,fields){ + switch(type){ + case "message": + const user=fields.get("user"); + const token=fields.get("token"); + const payload={ + notification: { + title: user+" ("+fields.get("room")+")", + body: fields.get("message"), + } + }; + firebase.messaging().sendToDevice(token,payload) + .then((response)=>{ + const result=response.results[0]; + const realToken=result.canonicalRegistrationToken; + if(result.error){ + console.error("JS: Send error:",result.error); + } else if(realToken&&realToken!=token){ + console.log("delete_token "+user+" "+token); + console.log("add_token "+user+" "+realToken); + } + }) + .catch((err)=>{ + console.error("JS: Early send error:",err); + }); + break; + + default: + console.error("JS: Unknown type '"+type+"'"); + } +} + +function handleInputLine(buffer){ + let idx=buffer.indexOf(32); + if(idx==-1){ + console.error("ERR: No space in input line"); + return; + } + const type=String(buffer.slice(0,idx)); + const fields=readFields(buffer.slice(idx+1)); + if(fields==null)return; + typeConvertFields(fields); + processMessage(type,fields); +} + + +{ + let buffer=null; + process.stdin.on("data",(data)=>{ + const prevlen=buffer==null?0:buffer.length; + if(buffer)buffer=Buffer.concat([buffer,data]); + else buffer=data; + let cursor=0; + let lfidx=buffer.indexOf(10,prevlen); + while(lfidx!=-1){ + handleInputLine(buffer.slice(cursor,lfidx)); + cursor=lfidx+1; + lfidx=buffer.indexOf(10,cursor); + } + if(cursor>=buffer.length)buffer=null; + else buffer=Buffer.from(buffer.slice(cursor)); + }); +} + +console.error("Firebase js plugin loaded!"); diff --git a/firebase-io/package.json b/firebase-io/package.json new file mode 100644 index 0000000..df6b578 --- /dev/null +++ b/firebase-io/package.json @@ -0,0 +1,23 @@ +{ + "name": "tomsg-firebase", + "version": "0.1.0", + "description": "Javascript part of firebase plugin to tomsg-server", + "main": "firebase-io.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://git.tomsmeding.com/tomsg" + }, + "keywords": [ + "tomsg", + "chat", + "firebase" + ], + "author": "Tom Smeding <tom.smeding@gmail.com> (https://tomsmeding.com)", + "license": "MIT", + "dependencies": { + "firebase-admin": "^4.2.1" + } +} |