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" +  } +} | 
