owned this note
owned this note
Published
Linked with GitHub
---
tags: mstu5013
---
# firebase review
## 1. router
in app.tag, we mounted a regular html menu.
in script tag, we implimented a router event listener that specifically listens to internal and external url changes. So every time, when url changes, it gets called and executes the command inside:
```javascript=
<script>
var that = this;
// default page when the website first loads
// show about page upon first loading the site
this.page = "about";
// Routing Function
// When user clicks a menu bar item, url changes
//route function below gets triggered
//page variable updates
route(function(urlFragment) {
// console.log(urlFragment);
that.page = urlFragment;
that.update();
});
// Start the router and execute it [true]
route.start(true);
</script>
```
Above, we then choose to hide and review part of this site depending on which url is clicked at the moment:
```javascript=
<!-- The riot show conditional will show an HTML element if the condition specified is true.
Otherwise the HTML element will be hidden.
If hidden, the HTML element will still be part of the HTML / DOM. -->
<memes show={ page === "memes" }></memes>
<admin show={ page === "admin" }></admin>
<about show={ page === "about" }></about>
```
## 2. firebase authentication
Next, in admin.tag, we implemented sign-in and a firebase listener to actively listen to sign-in status.
```javascript=
<script>
var tag = this;
// Firebase provide us with easy methods to sign-in and sign-out. We can access all Firebase authentication methods by creating an Auth Object via the following:
this.currentUser = firebase.auth().currentUser;
// Listener
user.onAuthStateChanged(function (userObj) {
tag.currentUser = firebase.auth().currentUser;
console.log("on stage change: this.currentUser", this.currentUser);
tag.update();
});
//sign-in with google
this.logIn = function () {
console.log("logging in...");
var provider = new firebase.auth.GoogleAuthProvider();
user.signInWithPopup(provider);
// firebase.auth()
}
</script>
```
## 3. firebase logout
private.tag, line 41-51
```javascript=
var tag= this;
// console.log("parent " ,this.parent.currentUser);
this.currentUser = user.currentUser;
// console.log(this.currentUser.uid);
// this.logOut = this.parent.logOut;
this.logOut = function () {
console.log("logging out...");
user.signOut();
}
```
## 4.firebase save
private.tag, line 53-86
```javascript=
var myRef = rootRef.child('memes/private/' + tag.currentUser.uid);
//local database is always empty, and read dynamicly from fb.
this.myMemes = [];
//prepare to push into memes subdirectory in our database
this.saveMeme = function () {
let key = myRef.push().key;
let meme = {
id: key,
userID: this.currentUser.uid, //global google authenticated user object
public: false,
url: this.refs.urlEl.value,
caption: this.refs.captionEl.value,
funness: this.refs.funnyEl.value
}
//messagesRef.child(key).set(meme);
//set meme while catching potential error messages(optional)
myRef.child(key).set(meme).then(function (result) {
console.log(result);
}).catch(function (error) {
console.log(error.message);
});
this.reset();
}
this.reset = function () {
//clean up default input values
this.refs.urlEl.value = "";
this.refs.captionEl.value = "";
this.refs.funnyEl.value = "";
}
```
## 5. real-time firebase database listener to listen to private data update
private.tag, line 88-100.
```javascript=
// listen to database value change and update result
myRef.on('value', function (snap) {
let rawdata = snap.val();
// console.log("rawdata", rawdata);
let tempData = [];
for (key in rawdata) {
tempData.push(rawdata[key]);
}
// console.log("myMemes", tag.myMemes);
tag.myMemes = tempData;
tag.update();
observable.trigger('updateMemes', tempData);
});
```
## 5.1 real-time firebase database listener to listen to public data update
==important!== there is no longer a need for observable to pass data between tags. because you can always directly listen to realtime firebase data update on ANY tag of your choice.
memes.tag
```javascript=
<meme each={ myMeme in myPublicMemes }></meme>
<script>
var tag = this;
this.myPublicMemes = [];
var myRef = rootRef.child('memes/public/');
myRef.on('value', function (snap) {
let rawdata = snap.val();
// console.log("rawdata", rawdata);
let tempData = [];
for (key in rawdata) {
tempData.push(rawdata[key]);
}
// console.log("myMemes", tag.myMemes);
tag.myPublicMemes = tempData;
tag.update();
});
</script>
```
## 6. order result
private.tag, line 102-132.
```javascript=
orderResults() {
//1. get order value
let order = this.refs.order.value;
// console.log("order", order);
let orderResult = myRef;
console.log("myRef", myRef);
// if order is selected as funnies, then order messages by child propoerty funness if order is selected as caption, then order messages by child propoerty caption if order is elected as default, no need to reorder at specifically
if(order=="funness"){
orderResult = orderResult.orderByChild("funness");
}else if(order=="caption"){
orderResult = orderResult.orderByChild("funness");
}else if(order=="default"){
}
orderResult.once('value', function (snap) {
// let rawdata = snap.val(); console.log("datafromfb", datafromfb);
let tempData = [];
snap.forEach(function (child) {
tempData.push(child.val()); // NOW THE CHILDREN PRINT IN ORDER
});
tag.myMemes = tempData;
tag.update();
observable.trigger('updateMemes', tempData);
});
}
```
## 7. filter result
private.tag, line 134-168.
```javascript=
filterResults(event) {
//get current filter value
var fun = this.refs.fun.value;
//order memes by child property funnees
let queryResult = myRef.orderByChild('funness');
console.log("queryResult", queryResult);
//combine with additional functions to form complex queries
if (fun == "nofun") {
queryResult = queryResult.equalTo("0");
console.log("queryResult for no fun", queryResult);
} else if (fun == "veryfun") {
queryResult = queryResult.equalTo("5");
console.log("queryResult for very full", queryResult);
} else if (fun == "somewhatfun") {
queryResult = queryResult.startAt('1').endAt('4');
console.log("queryResult for some fun", queryResult);
} else {
//default, no query needed
}
queryResult.once('value', function (snap) {
let rawdata = snap.val();
// console.log("datafromfb", datafromfb);
let tempData = [];
for (key in rawdata) {
tempData.push(rawdata[key]);
}
// console.log("myMemes", tag.myMemes);
tag.myMemes = tempData;
tag.update();
observable.trigger('updateMemes', tempData);
});
}
```
## 8. delete single admin entry
==important!== ref.update() is almost the same as ref.set(), except that it doesn't delete what's already inside the database, but merge with it.
in firebase, setting value ==null== is equal to delete that data node.
admin_entry.tag, line 21 - 32
```javascript=
var messagesRef = rootRef.child('/memes');
// console.log("messagesRef", messagesRef);
this.remove = function () {
// console.log("this.id", this.id); remember how we pushed the unique key as a property of each meme?
var updates = {};
updates['public/' + this.myMeme.id] = null;
updates['private/' + this.myMeme.userID + '/' + this.myMeme.id] = null;
messagesRef.update(updates);
// rootRef.child("/memes/private/test").remove();
}
```
## 9. toggle private, public
admin_entry.tag, line 36-51
```javascript=
let updates = {};
this.toggle = function () {
this.myMeme.public = !this.myMeme.public;
updates['private/' + this.myMeme.userID + '/' + this.myMeme.id] = this.myMeme;
if (this.myMeme.public) {
// console.log("this.myMeme".this.myMeme);
updates['public/' + this.myMeme.id] = this.myMeme;
} else {
updates['public/' + this.myMeme.id] = null;
}
// console.log("this.myMeme", this.myMeme);
// console.log("updates", updates);
messagesRef.update(updates);
}
```