From 20bbb3c8ef4c4ad07c72ea703dfd6b4b0ab313bb Mon Sep 17 00:00:00 2001 From: Peter Svensson Date: Sun, 7 Jul 2019 10:32:47 +0200 Subject: [PATCH] addes storage-list and some supporting logic in storage-read --- README.md | 34 ++++++++++++++++++++++++++- firebase-config.js | 2 ++ package.json | 5 ++-- storage/storage-list.html | 49 +++++++++++++++++++++++++++++++++++++++ storage/storage-list.js | 48 ++++++++++++++++++++++++++++++++++++++ storage/storage-read.js | 41 +++++++++++++++++++++++++------- storage/storage-write.js | 4 ++-- 7 files changed, 170 insertions(+), 13 deletions(-) create mode 100644 storage/storage-list.html create mode 100644 storage/storage-list.js diff --git a/README.md b/README.md index 4cce8bb..56c73ad 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ in any function like this; node.send( {payload: {data: d}}); }) +The cloud-storage reference is also made available under the global context variable 'cloud-storage'. + # Realtime Database (rtdb) Nodes ## rtdb-get @@ -104,7 +106,14 @@ output: An array of the results of the query. Read file data from 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"}} +input: + + { + "payload": { + "bucket": "xyzzyz123.appspot.com", + "path": "myFile.txt" + } + } npm publish .output: Buffer object containing the binary file contents. Can easily be converted to a string by calling toString() on the Buffer. @@ -125,6 +134,29 @@ input: } } +## storage-list +Lists the contents of files in a bucket + +If "path" is defined in the payload, only files beginning with that path will be returned. I fomitted, the root level of the bucket is listed. +A path can also be deep likes this; "foo/bar/baz". "delimiter" is the charatcer used to delimit directory levels, "/" by default. + +input: + + { + "payload": { + "bucket": "xyzzyz123.appspot.com", // optional + "path": "directory1", // optional + "delimiter": "/" // optional + } + } + +output: An array of google cloud-storage File objects. If you take this output and send it to a function which outputs a payload like this; + + {"files": array_of_File_obejcts} + +The storage-read module will read all file contents and output an array of Buffer objects instead of the normal one. + + # Auth nodes diff --git a/firebase-config.js b/firebase-config.js index 02f45df..b941964 100644 --- a/firebase-config.js +++ b/firebase-config.js @@ -38,6 +38,8 @@ module.exports = function(RED) { credentials: this.credentials }) + global.set('cloud-storage', s) + //s = new Storage() } } diff --git a/package.json b/package.json index 7d69044..5333f02 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-firebase-admin", - "version": "1.0.8", + "version": "1.0.9", "description": "A node-red module that wraps the server-side admin SDK of firebase, firestore, et.c.", "main": "index.js", "scripts": { @@ -33,7 +33,8 @@ "flow-to-rtdb": "rtdb/flow-to-rtdb.js", "rtdb-to-flow": "rtdb/rtdb-to-flow.js", "storage-read": "storage/storage-read.js", - "storage-write": "storage/storage-write.js" + "storage-write": "storage/storage-write.js", + "storage-list": "storage/storage-list.js" } }, "dependencies": { diff --git a/storage/storage-list.html b/storage/storage-list.html new file mode 100644 index 0000000..4cb7fc0 --- /dev/null +++ b/storage/storage-list.html @@ -0,0 +1,49 @@ + + + + + \ No newline at end of file diff --git a/storage/storage-list.js b/storage/storage-list.js new file mode 100644 index 0000000..3b0e139 --- /dev/null +++ b/storage/storage-list.js @@ -0,0 +1,48 @@ + + +let oldpath + +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.admin = c.admin + this.storage = c.storage + this.bucket = config.bucket || c.bucket + this.path = config.path + } + this.delimiter = config.delimiter + + //console.log('configuring storage-list to listen for messages') + node.on('input', function(msg) { + if(msg && msg.payload){ + 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+'"') + const options = { + prefix: path + }; + + if(this.delimiter){ + options.delimiter = this.delimiter + } + +// Lists files in the bucket, filtered by a prefix + this.storage.bucket(bucket).getFiles(options).then((files)=>{ + console.log('got file listing') + //console.dir(files[0]) + let f = files[0].filter((e)=>{ return e.name[e.name.length-1] !== '/' }) + node.send({payload: {files: f}}) + }) + } + }.bind(this)); + + + } + RED.nodes.registerType("storage-list", FirebaseAdmin); +} \ No newline at end of file diff --git a/storage/storage-read.js b/storage/storage-read.js index 0c4b1a3..1493dbb 100644 --- a/storage/storage-read.js +++ b/storage/storage-read.js @@ -22,15 +22,40 @@ module.exports = function(RED) { if(msg && msg.payload){ let path = msg.payload.path || this.path let bucket = msg.payload.bucket || this.bucket - console.log('storage-read reading from bucket "'+bucket+'" path "'+path+'"') - this.storage - .bucket(bucket) - .file(path).download().then((file)=>{ - console.log('storage-read got file') - //console.dir(file) - node.send({payload:file}) + console.log('------------------------------ storage-read reading from bucket "'+bucket+'" path "'+path+'"') + if(msg.payload.files && msg.payload.files.length > 0){ + console.log('--reading from files') + let count = msg.payload.files.length + let rv = {} + msg.payload.files.forEach((_file)=>{ + ((file)=>{ + console.log('reading file '+file.name) + this.storage + .bucket(bucket) + .file(file.name).download().then((content)=>{ + console.log('storage-read got file '+file.name) + rv[file.name] = content + if(--count === 0){ + console.log('all files done, sending..') + for(let x in rv){ + console.log(x) + } + node.send({payload:rv}) + } + }) + })(_file) + }) + } else { + console.log('reading single file from path '+path) + this.storage + .bucket(bucket) + .file(path).download().then((file)=>{ + console.log('storage-read got file') + //console.dir(file) + node.send({payload:file}) - }) + }) + } } }.bind(this)); diff --git a/storage/storage-write.js b/storage/storage-write.js index d01a822..996ab9b 100644 --- a/storage/storage-write.js +++ b/storage/storage-write.js @@ -26,8 +26,8 @@ module.exports = function(RED) { private: msg.payload.private || true, public: msg.payload.public || true, } - console.log('storage-write writing file to bucket "'+bucket+'" path "'+path+'"') - console.dir(msg.payload) + console.log('storage-write writing file to bucket "'+bucket+'" path "'+path+'" contents is of type '+(typeof contents)) + console.dir(contents) const myBucket = this.storage.bucket(bucket); const file = myBucket.file(path); file.save(contents, options, function(err) {