node-red-contrib-cloud-firestore
Version:
Node-RED nodes to handle google cloud firestore read and write operations.
152 lines (140 loc) • 6.08 kB
HTML
<script type="text/x-red" data-template-name="Firestore out">
<div class="firestore">
<div class="form-row">
<label for="node-input-admin"><i class="fa fa-cogs"></i> Admin</label>
<input type="text" id="node-input-admin">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Node Name </label>
<input type="text" id="node-input-name">
</div>
<div class="form-row">
<label for="node-input-operation"><i class="fa fa-wrench"></i> Operation </label>
<select name="operation" id="node-input-operation">
<option value="set">Set</option>
<option value="add">Add</option>
<option value="update">Update</option>
<option value="delete">Delete</option>
</select>
</div>
<div class="form-row">
<label for="node-input-collection"><i class="fa fa-archive"></i> Collection </label>
<input type="text" id="node-input-collection" placeholder="collection ref">
</div>
<div class="form-row">
<label for="node-input-document"><i class="fa fa-file"></i> Document </label>
<input type="text" id="node-input-document" placeholder="document ref">
</div>
<div class="collapsible">
<div class="form-row-header">Other Settings</div>
<div class="form-row" style="grid-template-columns: 3fr 4fr">
<label for="node-input-eject" style="width: 100%"><i class="fa fa-bolt"></i> Eject Firebase Object </label>
<input type="checkbox" id="node-input-eject">
</div>
</div
</div>
</div>
</script>
<script type="text/x-red" data-help-name="Firestore out">
<p>This node performs write operations to the referenced collection or document</p>
<h3>Inputs</h3>
<p>Data is received on the <code>msg.payload</code> property</p>
<p>Operation configurations are received on <code>msg.firestore</code> property with the following properties:</p>
<dl class="message-properties">
<dt>
operation <span class="property-type">string</span>
</dt>
<dd>The write operation to perform, either <code>add</code>, <code>set</code>, <code>update</code> or <code>delete</code></dd>
<dt>
collection <span class="property-type">string</span>
</dt>
<dd>The collection reference to write to</dd>
<dt class="optional">
document <span class="property-type">string</span>
</dt>
<dd>The document reference to write to</dd>
<dt class="optional">
eject <span class="property-type">boolean</span>
</dt>
<dd>Output the firebase app and admin instance on the <code>msg.firebase</code> property</dd>
</dl>
<h4>Note: set and update operations require a document reference</h4>
<p>
Sample:
<pre>msg.firestore = {
collection: 'farm',
document: 'cows',
operation: 'update'
}</pre>
</p>
<h3>Mustache Templating</h3>
<p>The node supports Mustache templating on the <code>collection</code> and <code>document</code> properties.</p>
<p>For Example:</p>
<pre>msg = {
collection: 'foo',
document: 'bar'
}</pre>
<p>With the <code>collection</code> property set to <code>{{collection}}</code> and the <code>document</code> property set to <code>{{document}}</code> in the editor,
the target collection will be <code>foo</code> & document will be <code>bar</code>.</p>
<h3>Performing update operations</h3>
<p>Due to the nature of firestores implementation, some actions need special handling.</p>
<h4>Handling arrays</h4>
<p>
To perform array updates you may need to wrap your elements anywhere within the payload in an object with an <code>_arrayUnion</code> property for array pushes <br>
whereas to remove, you will need to use <code>_arrayRemove</code> as shown: <br>
<pre>{animals: {_arrayUnion: "goats"},
farmers: {_arrayRemove: {name: "John Doe"}}}</pre>
becomes:
<pre>{animals: firestore.FieldValue.arrayUnion("goats"),
farmers: firestore.FieldValue.arrayRemove({name: "John Doe"})}</pre>
</p>
<h4>Handling GeoPoints</h4>
<p>Properties within the received payload containing a <code>latitude</code> and <code>longitude</code> property will be
automatically converted to a <a href="https://firebase.google.com/docs/reference/admin/node/admin.firestore.GeoPoint">Firestore GeoPoint</a> as shown</p>
<pre>{location: {_lat: -1.232,_lng: 36.343}}</pre>
becomes:
<pre>{location: new firestore.GeoPoint(_lat, _lng)}</pre>
<h4>Delete</h4>
<p>Properties with the <code>_delete</code> string value will be replaced with the appropriate <a href="https://firebase.google.com/docs/reference/admin/node/admin.firestore.FieldValue#.delete">delete</a> sentinel
<pre>{unwantedField: '_delete'}</pre>
becomes:
<pre>{unwantedField: firestore.FieldValue.delete()}</pre>
</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('Firestore out', {
category: 'firebase',
defaults: {
name: {required: false},
collection: {required: false},
document: {required: false},
operation: {
required: true,
value: "set",
validate: function (val) {
return val === 'set' || val === 'add' || val === 'update' || val === 'delete'
}
},
admin: {type: "firebase admin", required: true},
eject: {required: false, value: false}
},
color: "#F3B567",
inputs: 1,
outputs: 1,
icon: "file.png",
align: "right",
label: function () {
return this.name || (this.collection && this.operation ? `${this.operation} ${this.collection}` : 'Firestore Write')
},
labelStyle: function () {
return (this.collection && !this.name) ? "node_label_italic" : "";
},
oneditprepare: function () {
// Other settings accordion
$('.collapsible').accordion({
collapsible: true,
active: this.eject ? 0 : false
});
}
});
</script>