Public
Edited
Mar 23, 2024
17 stars
Insert cell
Insert cell
import { firebase, listen, viewof user } with {
firebaseConfig
} from '@tomlarkworthy/firebase'
Insert cell
// Copy and paste the config object from the Firebase project settings for a web application
firebaseConfig = ({
apiKey: "AIzaSyBN4bxw6d0cM0CGPNzRrkRlBqwFQnPLdN4",
authDomain: "larkworthy-dfb11.firebaseapp.com",
databaseURL:
"https://larkworthy-dfb11-default-rtdb.europe-west1.firebasedatabase.app",
projectId: "larkworthy-dfb11",
storageBucket: "larkworthy-dfb11.appspot.com",
messagingSenderId: "786910701676",
appId: "1:786910701676:web:8d7dd002acf3b78c74d049",
uiConfig: {
// https://github.com/firebase/firebaseui-web#configuration
signInOptions: ["google.com", "anonymous"]
// tosUrl: '<your-tos-url>', // Terms of service url.
// privacyPolicyUrl: '<your-privacy-policy-url>', // Privacy policy url.
}
})
Insert cell
md`Its useful to assign SDK services to variable so autocomplete works`
Insert cell
firestore = firebase.firestore()
Insert cell
firestore
Insert cell
Insert cell
Insert cell
firestore.doc("messages/5h126rZvETtk4U010ueQ").set({
by: user.uid,
msg: "Hello"
})
Insert cell
Insert cell
(await firestore.doc("messages/5h126rZvETtk4U010ueQ").get()).data()
Insert cell
Insert cell
(await firestore.collection("messages").get()).docs.map(d => d.data())
Insert cell
Insert cell
listen(firestore.collection("messages").limit(2))
Insert cell
Insert cell
Insert cell
import { reconcile } from '@tomlarkworthy/reconcile-nanomorph'
Insert cell
messages = listen(
firestore
.collection("messages")
.orderBy("t")
.limitToLast(20)
)
Insert cell
Insert cell
messagesWithURL = promiseRecursive(
messages.map(row => ({
...row,
...(row.path && { url: storage.ref(row.path).getDownloadURL() })
}))
)
Insert cell
// Thanks you trincot!
// https://stackoverflow.com/a/44072329/862295
// A wonderful peice of code contralises all promises in a nexted object to the root.
function promiseRecursive(obj) {
const getPromises = obj =>
Object.keys(obj).reduce(
(acc, key) =>
Object(obj[key]) !== obj[key]
? acc
: acc.concat(
typeof obj[key].then === "function"
? [[obj, key]]
: getPromises(obj[key])
),
[]
);
const all = getPromises(obj);
return Promise.all(all.map(([obj, key]) => obj[key])).then(
responses => (
all.forEach(([obj, key], i) => (obj[key] = responses[i])), obj
)
);
}
Insert cell
ui = {
return reconcile(
this,
html`<table>
${messagesWithURL.map(row =>
row.url
? html`<tr><td width="100px">${row.by}</td><td><img width="400px" src=${row.url}></img></td></tr>`
: html`<tr><td width="100px">${row.by}</td><td>${row.msg}</td></tr>`
)}
</table>
<input onkeypress=${evt => {
mutable msgEvt = evt;
}}><br>

<input type="file" onchange=${evt => {
mutable fileEvt = evt;
}}>

`
);
}
Insert cell
mutable msgEvt = undefined
Insert cell
msgEvt.key
Insert cell
proccessMessage = {
if (msgEvt.key == "Enter") {
firestore.collection("messages").add({
by: user.uid,
msg: msgEvt.target.value,
t: firebase.firebase_.firestore.FieldValue.serverTimestamp()
});
}
}
Insert cell
msgEvt.target.value
Insert cell
mutable fileEvt = undefined
Insert cell
storage = firebase.storage()
Insert cell
sRef = storage.ref(`/examples/chat/${randomId()}`)
Insert cell
processFiles = {
const file = fileEvt.target.files[0];
const sRef = storage.ref(`/examples/chat/${randomId()}`);
const result = await sRef.put(file);
const path = result.ref.fullPath;
firestore.collection("messages").add({
by: user.uid,
path: path,
t: firebase.firebase_.firestore.FieldValue.serverTimestamp()
});
}
Insert cell
Insert cell
Insert cell
viewof user
Insert cell
user.uid
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more