diff --git a/README.md b/README.md index 9a94563..49923bc 100644 --- a/README.md +++ b/README.md @@ -42,12 +42,12 @@ output: whatever data was at the path "foo/bar" in the rtdb database, when chang ## rtdb-set Set data at a path in the rtdb database. Use "on" snapshot so will fire every time the data at the path changes and so drive flow execution from that point. -input: {"payload": {"path": "foo/bar", "obj": {"the": "object"}} +input: {"payload": {"path": "foo/bar", "obj": {"the": "object"}}} ## rtdb-push Pushes the new object onto an array under the path -input: {"payload": {"path": "foo/bar", "obj": {"the": "object"}} +input: {"payload": {"path": "foo/bar", "obj": {"the": "object"}}} ## rtdb-query Set up a reactive query for a path in the rtdb database. @@ -181,7 +181,20 @@ output: An array of google cloud-storage File objects. If you take this output a The storage-read module will read all file contents and output an object of filename keyed Buffer objects instead of the normal one. - +## storage-delete +Deletes a file at a given path under a given cloud storage bucket. The default bucket to be used can be set in the general firebase SDK settings. +If the payload defines an optional bucket property, it will override the default bucket settings. + +input: + + { + "payload": { + "bucket": "xyzzyz123.appspot.com", + "path": "myFile.txt" + } + } + +output: An array of headers returned by the operation if all went well. These are mostly useless but at least a confirmation of success. # Auth nodes diff --git a/firestore/firestore-get.js b/firestore/firestore-get.js index d57e3df..7152017 100644 --- a/firestore/firestore-get.js +++ b/firestore/firestore-get.js @@ -12,7 +12,7 @@ module.exports = function(RED) { this.admin = c.admin } - const setup = ()=>{ + const setup = (path)=>{ if(unsub){ unsub() } @@ -48,4 +48,4 @@ module.exports = function(RED) { } RED.nodes.registerType("firestore-get", FirebaseAdmin); -} \ No newline at end of file +} diff --git a/firestore/firestore-set.js b/firestore/firestore-set.js index cf74baf..cc7d011 100644 --- a/firestore/firestore-set.js +++ b/firestore/firestore-set.js @@ -14,10 +14,9 @@ module.exports = function(RED) { if(msg && msg.payload){ console.log('firestore-set got input') console.dir(msg) - const path = msg.payload.path - const obj = msg.payload.obj + const {path, obj, merge} = msg.payload console.log('storing '+obj+' at firestore path '+path) - this.admin.firestore().doc(path).set(obj).then((res)=>{ + this.admin.firestore().doc(path).set(obj, { merge }).then((res)=>{ console.log('firestore set result '+res) console.dir(res) }) @@ -27,4 +26,4 @@ module.exports = function(RED) { } RED.nodes.registerType("firestore-set", FirebaseAdmin); -} \ No newline at end of file +} diff --git a/package.json b/package.json index fc424ce..8c6b6bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-firebase-admin", - "version": "1.1.16", + "version": "1.1.22", "description": "A node-red module that wraps the server-side admin SDK of firebase, firestore, et.c.", "main": "index.js", "scripts": { @@ -39,7 +39,8 @@ "rtdb-to-flow": "rtdb/rtdb-to-flow.js", "storage-read": "storage/storage-read.js", "storage-write": "storage/storage-write.js", - "storage-list": "storage/storage-list.js" + "storage-list": "storage/storage-list.js", + "storage-delete": "storage/storage-delete.js" } }, "dependencies": { diff --git a/storage/storage-list.js b/storage/storage-list.js index 10228c0..dcb1e6a 100644 --- a/storage/storage-list.js +++ b/storage/storage-list.js @@ -10,7 +10,7 @@ module.exports = function(RED) { if(config.cred){ let c = RED.nodes.getNode(config.cred) this.admin = c.admin - this.storage = c.storage + this.config = c; this.bucket = config.bucket || c.bucket this.path = config.path } @@ -19,6 +19,8 @@ module.exports = function(RED) { //console.log('configuring storage-list to listen for messages') node.on('input', function(msg) { if(msg && msg.payload){ + let global = this.context().global + this.storage = this.config.storage || global.get('cloud-storage') let path = msg.payload.path || this.path let bucket = msg.payload.bucket || this.bucket console.log('storage-list listing files from bucket "'+bucket+'" path "'+path+'"') diff --git a/storage/storage-read.js b/storage/storage-read.js index db91a13..786bd30 100644 --- a/storage/storage-read.js +++ b/storage/storage-read.js @@ -9,25 +9,27 @@ module.exports = function(RED) { if(config.cred){ let c = RED.nodes.getNode(config.cred) + this.config = c; this.admin = c.admin - this.storage = c.storage - storage = this.storage + let global = this.context().global + this.storage = c.storage || global.get('cloud-storage') this.bucket = config.bucket || c.bucket this.path = config.path console.log('config is '+config) } - let global = this.context().global - this.storage = global.get('cloud-storage') - console.log('* storage-read set this.storage to '+this.storage) + //console.log('configuring storage-read to listen for messages') node.on('input', function(msg) { if(msg && msg.payload){ let path = msg.payload.path || msg.path || this.path let bucket = msg.payload.bucket || msg.bucket || this.bucket - console.log('------------------------------ storage-read reading from bucket "'+bucket+'" path "'+path+'" this.storage = '+this.storage+' storage = '+storage) + let global = this.context().global + this.storage = global.get('cloud-storage') + console.log('* storage-read set this.storage to '+this.storage) + console.log('------------------------------ storage-read reading from bucket "'+bucket+'" path "'+path+'" this.storage = '+this.storage) if(msg.payload.files && msg.payload.files.length > 0){ console.log('--reading from files') let count = msg.payload.files.length @@ -54,7 +56,7 @@ module.exports = function(RED) { } else if(msg){ console.log('* reading single file from path '+path) try{ - let s = this.storage || storage + let s = this.storage s.bucket(bucket) .file(path).download().then((file)=>{ console.log('storage-read got file') @@ -68,6 +70,7 @@ module.exports = function(RED) { }) } catch(ex){ console.log('storage-read caught exception: '+ex) + msg.payload = ex node.send(msg) } } else { diff --git a/storage/storage-write.js b/storage/storage-write.js index e43fc4b..29db4e6 100644 --- a/storage/storage-write.js +++ b/storage/storage-write.js @@ -1,54 +1,63 @@ - -module.exports = function(RED) { - +module.exports = function (RED) { function FirebaseAdmin(config) { RED.nodes.createNode(this, config); var node = this; + if (config.cred) { + let c = RED.nodes.getNode(config.cred); + this.config = c; + this.admin = c.admin; - if(config.cred){ - let c = RED.nodes.getNode(config.cred) - this.admin = c.admin - this.storage = c.storage - this.bucket = config.bucket || c.bucket - this.path = config.path - /* - console.log('configuring storage-write to listen for messages. config is') - console.dir(config) - console.log('storage is') - console.dir(this.storage) - */ + this.bucket = config.bucket || c.bucket; + this.path = config.path; } - - node.on('input', function(msg) { - if(msg && msg.payload){ - let path = msg.payload.path || msg.path|| this.path - let bucket = msg.payload.bucket || msg.bucket || this.bucket - let contents = msg.payload.contents || msg.payload - let options ={ - contentType: msg.payload.contentType || msg.contentType || 'auto', - metadata: msg.payload.metadata || msg.metadata || {}, - private: msg.payload.private || msg.private || true, - public: msg.payload.public || msg.public || true, - } - console.log('storage-write writing file to bucket "'+bucket+'" path "'+path+'" contents is of type '+(typeof contents)) - const myBucket = this.storage.bucket(bucket); - const file = myBucket.file(path); - file.save(contents, options, function(err) { - if (!err) { - // File written successfully. - msg.payload={success:true, filename: path} - } else { - console.log('cloud storage write error: '+err) - msg.payload ={success:false, filename: path} + node.on( + "input", + function (msg) { + try { + if (msg && msg.payload) { + let global = this.context().global; + this.storage = this.config.storage || global.get("cloud-storage"); + let path = msg.payload.path || msg.path || this.path; + let bucket = msg.payload.bucket || msg.bucket || this.bucket; + let contents = msg.payload.contents || msg.payload; + let options = { + contentType: msg.payload.contentType || msg.contentType || "auto", + metadata: msg.payload.metadata || msg.metadata || {}, + private: msg.payload.private || msg.private || true, + public: msg.payload.public || msg.public || true, + }; + console.log( + 'storage-write writing file to bucket "' + + bucket + + '" path "' + + path + + '" contents is of type ' + + typeof contents + ); + const myBucket = this.storage.bucket(bucket); + const file = myBucket.file(path); + file.save(contents, options, function (err) { + if (!err) { + // File written successfully. + msg.payload = { success: true, filename: path }; + } else { + console.log( + "cloud storage write error: " + JSON.stringify(err) + ); + msg.payload = { success: false, filename: path }; + } + node.send(msg); + }); } - node.send(msg) - }); - } - }.bind(this)); - - + } catch (ex) { + console.log("storage-read caught exception: " + ex); + msg.payload = ex; + node.send(msg); + } + }.bind(this) + ); } RED.nodes.registerType("storage-write", FirebaseAdmin); -} \ No newline at end of file +};