Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This is a quick outline of building an web service with these constraints:
- some kind of cloud hosting; ie; visibile anywhere on the internet, no fretting over back end unix installs
- presents a user editable fillable form on a web page
- saves that user supplied form data to persistent state on the server
- signs the user supplied information with a private key
- does some secure server side transactionally bound database actions
- returns a result to the user
I've been using firebase lately and I'd definitely do it this way if I was asked to do a quick one off.
Here's how I would do it from scratch:
1)
I'd declare a new firebase app at https://console.firebase.google.com/ .
I would take this opportunity to enable firebase hosting (so that it can have a website).
I'd also enable firebase firestore (as opposed to the similarily named firebase realtime database)
2)
Then, you have to fetch the firebase CLI - bringing tools down to your own computer.
They have an incantation to initialize a new firebase project and it does most of the work of declaring files/folders.
The firebase paradigm is that you edit your own files on your own machine.
To "deploy" your changes to their servers you have to type "firebase deploy"....
3)
Then I'd find where they put the client side index.html file and I would throw theirs out and add something like this instead:
<html>
<body>
<script src="/__/firebase/8.1.2/firebase-app.js"></script>
<script src="/__/firebase/8.1.2/firebase-analytics.js"></script>
<script src="/__/firebase/8.1.2/firebase-auth.js"></script>
<script src="/__/firebase/8.1.2/firebase-firestore.js"></script>
<input id="myfield1"></input>
<input id="myfield2"></input>
<button>submit</button>
</body>
</html>
<script>
// get the first button and decorate it with an onclick handler
document.body.querySelector("button").onclick = async (e) => {
// get all the input as a hashtable of key value pairs
let inputs = [..document.body.querySelectorAll("input")]
let saveme = Object.fromEntries(inputs.map(input => [input.id, input.value]) )
// build the magic incantation to a server side function
let mymagic = firebase.functions().httpsCallable("mymagic")
// call it - and might as well wait for response i suppose
let results = await mymagic(saveme)
// do something with results? could change the page here or something; deal with success/fail
}
</script>
4) Then I'd write the server side - it would go into a special index.js file that they have in a folder called 'server'.
I'd throw theirs away and I'd write something like this:
const admin = require('firebase-admin')
const functions = require('firebase-functions')
let mydatabasetable = admin.firestore().collection('mydatabasetable'),
exports.mymagic = functions.https.onCall( async (data,context) => {
let saveme = data.saveme
await mydatabasetable.doc().set(saveme,{merge:true})
// maybe wrap a transaction block around this like so https://firebase.google.com/docs/firestore/manage-data/transactions
// maybe pull in a crypto library to sign this... (I do this often and I can recommend some)
// return a signed result...
return "this is the signed result"
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment