cd path/to/project
npm install
npm start
always do this!
A "web backend solution"
{
"key":{
"property":"value",
"property":"value"
},
"key":"value",
...
}
index.js
import firebase from 'firebase'; //import library
// Configure Firebase (replace with your app data)
// refresh the page if any fields are blank!
var config = {
apiKey: "apiKey",
authDomain: "projectId.firebaseapp.com",
databaseURL: "https://databaseName.firebaseio.com",
storageBucket: "bucket.appspot.com"
};
firebase.initializeApp(config);
Use logic in your render() function to decide what HTML elements to show.
class LoginControl extends React.Component {
render() {
var isLoggedIn = this.props.isLoggedIn;
var button = null;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(function(firebaseUser) {
console.log('user created: '+firebaseUser.uid);
//...
})
.catch(function(error) { //report any errors--useful!
console.log(error);
});
React components have a number of "lifecycle methods" that are automatically called by the framework when the components are added or removed from the DOM. You can override these methods to specify actions that should occur at these times.
class MyComponent extends React.Component {
constructor(props) {
super(props);
// called when element is created,
// but may not be added to the DOM yet!
}
componentDidMount() {
// called when component has been added to the DOM
}
componentWillUnmount() {
// called when component about to be removed
}
}
firebase.auth().onAuthStateChanged(firebaseUser => {
if(firebaseUser){
console.log('logged in');
//assign firebaseUser.uid to `userId` using this.setState()
}
else {
console.log('logged out');
//assign null to `userId` using this.setState()
}
});
ES 6 provides a
shortcut syntax for declaring functions using
=>
//normal function declaration
let foo = function(param) {
return 'foo '+param;
}
//arrow function declaration (block body)
let foo = (params) => {
return 'foo '+params;
}
//arrow function declaration (concise body)
let foo = (params) => 'foo '+params;
single expression implies return
//arrow function declaration (concise body)
let sayHello = (name) => console.log('Hello '+name);
anonymous function assigned to a variable
ES 6 provides a
shortcut syntax for declaring functions using
=>
//normal function declaration
let array = [1,2,3];
array.map(function(num) {
return num*2; //multple each item by 2
});
//arrow function declaration (block body)
let array = [1,2,3];
array.map(num => {
return num*2; //multple each item by 2
});
//arrow function declaration (concise body)
let array = [1,2,3];
array.map(num => num*2);
ES 6 provides a
shortcut syntax for declaring functions using
=>
//normal function declaration
let array = [1,2,3];
array.map(function() { //no params! (for reasons)
return 12; //map everything to 12
});
//arrow function declaration (block body)
let array = [1,2,3];
array.map(() => {
return 12; //map everything to 12
});
//assign function to a name
let make12 = () => 12;
//arrow function declaration (concise body)
//assign function to a name
let make12 = function() {
return 12;
};
Syntactic Sugar causes cancer of the semicolon
Arrow functions do not create their own this context, so that the this will continue to refer to the contained scope
class MyComponent extends React.Component {
fetchData() {
var thisComponent = this; //1. save "this" for later
fetch(url)
.then(function(res) {return res.json();};
.then(function(data) {
thisComponent.setState({ /*...*/ }); //2. use saved "this"
});
}
}
remember this problem?
class MyComponent extends React.Component {
fetchData() {
fetch(url)
.then(function(res) {return res.json();};
.then(data => {
this.setState({ /*...*/ });
});
}
}
this refers to "outer" (component) scope
class MyComponent extends React.Component {
fetchData() {
fetch(url)
.then(res => res.json());
.then(data => this.setState({ /*...*/ }) );
}
}
Specify who can access what elements in the "JSON Object in the Cloud"
{
"rules": {
".read": true,
"users": {
"$uid": {
".write": "auth.uid === $uid"
}
}
}
}
Get a reference variable (think "url") for an element in the database.
//get reference to the "root" of the database: the containing JSON
var rootRef = firebase.database().ref();
//refers to the "users" value in the database
var usersRef = firebase.database().ref('users');
//refers to the "ada" value inside the "users" value in the database
var adaUserRef = firebase.database().ref('users/ada');
var array = ['a', 'b', 'c'];
Given an array:
//add element 'ab' at index 1 (between 'a' and 'b')
array.splice(1, 0, 'ab');
Person 1 says:
//change element at index 1 (the 'b') to 'B'
array[1] = 'B';
Person 2 says:
var array = ['a', 'ab', 'B', 'c']; // ??
What does the array look like??
var array = ['a', 'B', 'c']; // ??
var usersRef = firebase.database().ref('users');
usersRef.on('value', (snapshot) => {
var newVal = snapshot.val();
this.setState({users:newVal});
});
reference to value in db
register listener
listen for value changes
arrow function so `this` stays in scope
convert "firebase object" into normal JavaScript value
Finish up React Challenge
Chat Room Challenge will be finished soon
Lab: Team formation and GitHub practice
Show up to get on a team!!
Wed: Single-page applications