[codorial] proof read changes

This commit is contained in:
Elliot Hesp 2018-03-05 10:50:25 +00:00
parent 040f3333c7
commit ec0dbb267f
7 changed files with 33 additions and 31 deletions

View File

@ -4,7 +4,7 @@ React Navigation has gone through many cycles of navigation implementations and
A current "go to" navigation library is called [react-navigation](https://reactnavigation.org/). It's pure JavaScript implementation A current "go to" navigation library is called [react-navigation](https://reactnavigation.org/). It's pure JavaScript implementation
which performs well and provides a solid foundation for navigation on both Android and iOS. which performs well and provides a solid foundation for navigation on both Android and iOS.
Authentication typically requires 3 screens; Login, Register & Forgot Password. In this step we'll be focusing on adding a Login & Register screen to our app.
## Installation ## Installation
@ -103,7 +103,7 @@ library provides a simple, React like API to style and control your app.
For this example we're going to add a title to our screen and liven up the colors - there's loads more you can do with `react-navigation` though, For this example we're going to add a title to our screen and liven up the colors - there's loads more you can do with `react-navigation` though,
just check out their in-depth [documentation](https://reactnavigation.org/docs/getting-started.html). just check out their in-depth [documentation](https://reactnavigation.org/docs/getting-started.html).
Lets go ahead and style the screen, using a class static `navigationOptions` object which lets `react-navigation` access our screen component: Lets go ahead and style the screen, using a class static `navigationOptions` object which lets `react-navigation` access our screen component styling:
```jsx ```jsx
// src/screens/unauthenticated/Login.js // src/screens/unauthenticated/Login.js

View File

@ -9,13 +9,13 @@ The Firebase API allows us to call `signInAndRetrieveDataWithCredential` with a
## Installing `react-native-fbsdk` ## Installing `react-native-fbsdk`
Luckily as Facebook own React Native, they provide a handy wrapper around the own SDK to integrate with React Native, called [`react-native-fbsdk`](https://github.com/facebook/react-native-fbsdk). Luckily as Facebook own React Native, they provide a handy wrapper around their own SDK to integrate with React Native, called [`react-native-fbsdk`](https://github.com/facebook/react-native-fbsdk).
```bash ```bash
npm install --save react-native-fbsdk npm install --save react-native-fbsdk
``` ```
To save explaining how to install this library, refer to their [documentation[(https://developers.facebook.com/docs/react-native) on how to To save explaining how to install this library, refer to their [documentation](https://developers.facebook.com/docs/react-native) on how to
install the library into your React Native project on both Android & iOS. install the library into your React Native project on both Android & iOS.
## Creating a credential ## Creating a credential

View File

@ -1,18 +1,18 @@
# Getting Started # Getting Started
Welcome to the 'Authentication with Firebase' Codorial using the [react-native-firebase](https://rnfirebase.io) library. Welcome to the 'Authentication with Firebase' Codorial, using [React Native](http://facebook.github.io/react-native/) and [react-native-firebase](https://rnfirebase.io).
The various steps of the Codorial will cover how to setup your application to require both email/password login and social login using Facebook, Over the Codorial we'll cover how to setup your application to require both email/password login and social login using Facebook,
to handling the users authenticated state using the popular [redux](https://redux.js.org/introduction) library whilst also considering integrate routing to handling the users authenticated state using the popular [redux](https://redux.js.org/introduction) library whilst also integrating routing
using [react-navigation](https://reactnavigation.org/). using [react-navigation](https://reactnavigation.org/).
## Prerequisites ## Prerequisites
This Codorial assumes you know the basics of the following topics: This Codorial assumes you know the basics of the following topics:
- React JS.
- ES6 JavaScript. - ES6 JavaScript.
- Starting your app using an emulator on Android/iOS. - Starting an app using an emulator on Android/iOS.
- Understand how to setup a new Firebase project. - Understand how to setup a new Firebase project.
- Debugging with React Native.
- Managing your project using Android Stuido and/or XCode. - Managing your project using Android Stuido and/or XCode.
- Installation of the [react-native-firebase](https://rnfirebase.io) library (see "Creating a base project" below). - Installation of the [react-native-firebase](https://rnfirebase.io) library (see "Creating a base project" below).

View File

@ -52,7 +52,7 @@ export default App;
## Updating Redux with the user state ## Updating Redux with the user state
Rather than passing our `user` into component `state`, we're going to add into into Redux instead. Firebase does provide direct access to the user Rather than passing our `user` into component `state`, we're going to add it into into Redux instead. Firebase does provide direct access to the user
via `firebase.auth().currentUser`, however as our app complexity grows we may want to integrate parts of the users data (for example the `uid`) into via `firebase.auth().currentUser`, however as our app complexity grows we may want to integrate parts of the users data (for example the `uid`) into
other parts of our Redux store. By storing the user in Redux, it is guaranteed that the user details will keep in-sync throughout our Redux store. other parts of our Redux store. By storing the user in Redux, it is guaranteed that the user details will keep in-sync throughout our Redux store.
@ -77,8 +77,8 @@ export function userStateChanged(user) {
} }
``` ```
To dispatch this action we need to again make use of `react-redux`. As our `App.js` has been provided the Redux store within `index.js` we can To dispatch this action we need to again make use of `react-redux`. As our `App.js` has been provided the Redux store via the `Provider`
use a [higher order component (HOC)](https://reactjs.org/docs/higher-order-components.html) called `connect` to provide the component with access to Redux: component within `index.js`, we can use a [higher order component (HOC)](https://reactjs.org/docs/higher-order-components.html) called `connect` to provide the component with access to Redux:
```jsx ```jsx
// src/App.js // src/App.js
@ -90,7 +90,7 @@ import { connect } from 'react-redux';
export default connect()(App); export default connect()(App);
``` ```
The `connect` HOC clones the given component with a function prop called `dispatch`. The function then takes an action, which when called 'dispatches' The `connect` HOC clones the given component with a function prop called `dispatch`. The `dispatch` function then takes an action, which when called 'dispatches'
it to Redux. Lets jump back into our `App.js` and dispatch our action when `onAuthStateChanged` is triggered: it to Redux. Lets jump back into our `App.js` and dispatch our action when `onAuthStateChanged` is triggered:
```jsx ```jsx
@ -102,7 +102,6 @@ import { userStateChanged } from './actions';
... ...
componentDidMount() { componentDidMount() {
// Listen for user auth state changes
firebase.auth().onAuthStateChanged((user) => { firebase.auth().onAuthStateChanged((user) => {
// dispatch the imported action using the dispatch prop: // dispatch the imported action using the dispatch prop:
@ -158,7 +157,7 @@ previous state with a new one.
### Subscribing to Redux state ### Subscribing to Redux state
Now our user data is updating the store whenever it changes, we can subscribe to specific parts of the data which we need in out React Now our action is updating the store whenever it's dispatched, we can subscribe to specific parts of the data which we need in our React
components. The power of using `react-redux` is that it allows us to subscribe to data within our store and update the component whenever that components. The power of using `react-redux` is that it allows us to subscribe to data within our store and update the component whenever that
data changes - we do this via a function known as `mapStateToProps`. This function is passed as the first argument of our `connect` HOC and gets data changes - we do this via a function known as `mapStateToProps`. This function is passed as the first argument of our `connect` HOC and gets
given the current Redux state. It returns an object, which is cloned as props into our component. Here's how it works: given the current Redux state. It returns an object, which is cloned as props into our component. Here's how it works:
@ -174,7 +173,7 @@ export default connect(mapStateToProps)(App);
``` ```
With this code, our `App` component will receive a prop called `isUserAuthenticated`, which in our case will be a `true` or `false` value based on With this code, our `App` component will receive a prop called `isUserAuthenticated`, which in our case will be a `true` or `false` value based on
whether the `state.user` object exists or not. Every time Redux state changes, this logic is run. What's cool is that if the result of any whether the `state.user` object exists or not. Every time Redux state changes, this logic is run. What's handy is that if the result of any
prop has changed, the component will be updated with the new data. If none of the props-to-be have changed, the component doesn't update. prop has changed, the component will be updated with the new data. If none of the props-to-be have changed, the component doesn't update.
> Keep in mind that if you return a complex `Array` or `object`, `react-redux` will only shallow compare them. Even if your state does not change > Keep in mind that if you return a complex `Array` or `object`, `react-redux` will only shallow compare them. Even if your state does not change
@ -182,7 +181,7 @@ the component will still be re-rendered with the same data which can cause perfo
to break components out to only subscribe to specific parts of primitive state (such as `strings`, `booleans` etc). to break components out to only subscribe to specific parts of primitive state (such as `strings`, `booleans` etc).
As our `App` component contains our routes, any change in the `isUserAuthenticated` value will cause the entire app to re-render - which in this case As our `App` component contains our routes, any change in the `isUserAuthenticated` value will cause the entire app to re-render - which in this case
is fine as we're conditionally changing navigation stacks. Lets implement that: is fine as we're conditionally changing navigation stacks. Lets implement that logic:
```jsx ```jsx
// src/App.js // src/App.js
@ -192,6 +191,7 @@ import firebase from 'react-native-firebase';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import UnauthenticatedStack from './screens/unauthenticated'; import UnauthenticatedStack from './screens/unauthenticated';
import AuthenticatedStack from './screens/authenticated';
import { userStateChanged } from './actions'; import { userStateChanged } from './actions';
class App extends Component { class App extends Component {
@ -204,7 +204,6 @@ class App extends Component {
} }
componentDidMount() { componentDidMount() {
// Listen for user auth state changes
firebase.auth().onAuthStateChanged((user) => { firebase.auth().onAuthStateChanged((user) => {
this.props.dispatch(userStateChanged(user)); this.props.dispatch(userStateChanged(user));

View File

@ -4,10 +4,10 @@ Redux has become somewhat of a buzz word in the React community, and is generall
won't go into details on what it is as their own [documentation](https://redux.js.org/introduction/motivation) does a wonderful job at explaining won't go into details on what it is as their own [documentation](https://redux.js.org/introduction/motivation) does a wonderful job at explaining
what it's for and why to use it. what it's for and why to use it.
*TLDR* Redux provides your app with a single "state" (data), which can be accessed by any component. You can subscribe to this data to cause *TLDR;* Redux provides your app with a single "state" (data), which can be accessed by any component. You can subscribe to this data to cause
a component update whenever something changes, even if it's deeply nested. a component update whenever something changes, even if it's deeply nested.
Although the end product of this Codorial certain doesn't require Redux to function, as your app grows in complexity Redux becomes more and Although the end product of this Codorial certainly doesn't require Redux to function, as your app grows in complexity Redux becomes more and
more important to manage your data. more important to manage your data.
## Installing Redux ## Installing Redux
@ -33,9 +33,11 @@ function reducer(state = {}, action) {
export default createStore(reducer); export default createStore(reducer);
``` ```
As default state is `null`, we set the default to be an empty `object` so we can access it later on. By default state is `null`, however we're setting it to an empty `object` (`state = {}`) so we can attempt to access
shallow nested properties even if they don't exist.
> You may want to consider installing the [redux-logger](https://github.com/evgenyrodionov/redux-logger) library. > You may want to consider installing the [redux-logger](https://github.com/evgenyrodionov/redux-logger) library to improve
your Redux experience.
### Reducer ### Reducer

View File

@ -1,12 +1,13 @@
# Project Structure # Project Structure
Although it may seem trivial, having a good initial project structure ensures you code will be clean and reusable. The following step gives Although it may seem trivial, having a good initial project structure ensures your code will be clean and reusable.
an opinionated guide to how this might look, which will work across both Android & iOS. The following step gives an opinionated guide to how this might look, which will work across both Android & iOS.
## Entry file ## Entry file
Every fresh React Native project contains two key files, an `index.android.js` & a `index.ios.js` files which currently individually render a simple React component Every fresh React Native project a key file, an `index.js`, which currently renders a simple React component
with basic styling. Rather than having two separate files, we're going to create a single file so both Android & iOS use it. with basic styling. Rather than keeping our business logic within this file, we're going to keep it contained in it's own
directory.
We'll achieve this by creating a `src` directory where our own code for the app will live. Create the directory with an `index.js` file, so your We'll achieve this by creating a `src` directory where our own code for the app will live. Create the directory with an `index.js` file, so your
project structure resembles the following: project structure resembles the following:

View File

@ -8,12 +8,12 @@ Luckily [react-native-firebase](https://rnfirebase.io) follows the Firebase web
## Enabling authentication ## Enabling authentication
Before we make a start, we need to tell Firebase that we plan on using authentication. We need to also enable a couple of the many login providers We need to tell Firebase that we plan on using authentication and also enable a couple of the many login providers
which Firebase supports. Head over to the [Firebase console](https://console.firebase.google.com/u/0/) and select the project you're using. which Firebase supports. Head over to the [Firebase console](https://console.firebase.google.com/u/0/) and select the project you're using.
Find the Authentication section and you'll be prompted with a number of options. To get started, we want to select the "SIGN-IN METHOD" tab. Find the Authentication section and you'll be prompted with a number of options. To get started, we want to select the "SIGN-IN METHOD" tab.
You'll see we have a number of options here, however for purposes of this Codorial we'll be using "Email/Password" and "Facebook" as our providers. You'll see we have a number of options here, however for the purposes of this Codorial we'll be using "Email/Password" and "Facebook" as our providers.
Go ahead and enable these: Go ahead and enable these:
![Enabled Providers](assets/auth-providers.jpg) ![Enabled Providers](assets/auth-providers.jpg)
@ -38,7 +38,7 @@ The callback for the `onAuthStateChanged` method returns a single parameter, com
The concept here is simple; The concept here is simple;
- the method is first called once Firebase responds, then any time user state changes thereafter. - the method is first called once Firebase responds, then any time user state changes thereafter.
- if a user is "signed in", our parameter will be a `class`, containing all sorts of information we know about the user, - if a user is "signed in", our parameter will be a [`User`](https://firebase.google.com/docs/reference/js/firebase.User) `class`, containing all sorts of information we know about the user,
from their e-mail address to any social provider IDs they may have signed in through. from their e-mail address to any social provider IDs they may have signed in through.
- if the user signed out, the parameter will be `null` value. - if the user signed out, the parameter will be `null` value.
@ -68,7 +68,7 @@ firebase.auth().createUserAndRetrieveDataWithEmailAndPassword('jim.bob@gmail.com
}); });
``` ```
What's great about this is we don't need to know about the user within the `then`, as any `onAuthStateChanged` listener would get triggered with our new What's great about this is we don't need to know about the user within the `.then`, as any `onAuthStateChanged` listener would get triggered with our new
users details - how awesome is that. users details - how awesome is that.
## Signing into an existing account ## Signing into an existing account
@ -157,7 +157,7 @@ When subscribing to a new listener, such as `onAuthStateChanged`, a new referenc
React environment. If a component within your app mounts and subscribes, the method will still trigger even if your component unmounted. React environment. If a component within your app mounts and subscribes, the method will still trigger even if your component unmounted.
If this happens and you're updating state, you'll get a yellow box warning. If this happens and you're updating state, you'll get a yellow box warning.
To get around this, Firebase returns an unsubscribe function to every subscriber method, which when calls removes the subscription. To get around this, Firebase returns an unsubscribe function to every subscriber method, which when calls removes the subscription from memory.
This can be easily implemented using React lifecycle methods and class properties: This can be easily implemented using React lifecycle methods and class properties:
```jsx ```jsx