diff --git a/codorials/authentication-with-firebase/app-navigation.md b/codorials/authentication-with-firebase/app-navigation.md index 0c866b6e..060effd2 100644 --- a/codorials/authentication-with-firebase/app-navigation.md +++ b/codorials/authentication-with-firebase/app-navigation.md @@ -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 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 @@ -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, 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 // src/screens/unauthenticated/Login.js diff --git a/codorials/authentication-with-firebase/facebook-login.md b/codorials/authentication-with-firebase/facebook-login.md index 37761e87..5e51cd4a 100644 --- a/codorials/authentication-with-firebase/facebook-login.md +++ b/codorials/authentication-with-firebase/facebook-login.md @@ -9,13 +9,13 @@ The Firebase API allows us to call `signInAndRetrieveDataWithCredential` with a ## 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 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. ## Creating a credential diff --git a/codorials/authentication-with-firebase/getting-started.md b/codorials/authentication-with-firebase/getting-started.md index 81fb50af..36706452 100644 --- a/codorials/authentication-with-firebase/getting-started.md +++ b/codorials/authentication-with-firebase/getting-started.md @@ -1,18 +1,18 @@ # Getting Started -Welcome to the 'Authentication with Firebase' Codorial using the [react-native-firebase](https://rnfirebase.io) library. -The various steps of the Codorial will 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 +Welcome to the 'Authentication with Firebase' Codorial, using [React Native](http://facebook.github.io/react-native/) and [react-native-firebase](https://rnfirebase.io). +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 integrating routing using [react-navigation](https://reactnavigation.org/). ## Prerequisites This Codorial assumes you know the basics of the following topics: +- React JS. - 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. -- Debugging with React Native. - 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). diff --git a/codorials/authentication-with-firebase/handling-authentication-state.md b/codorials/authentication-with-firebase/handling-authentication-state.md index f85a488b..aad1724b 100644 --- a/codorials/authentication-with-firebase/handling-authentication-state.md +++ b/codorials/authentication-with-firebase/handling-authentication-state.md @@ -52,7 +52,7 @@ export default App; ## 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 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 -use a [higher order component (HOC)](https://reactjs.org/docs/higher-order-components.html) called `connect` to provide the component with access to Redux: +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` + 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 // src/App.js @@ -90,7 +90,7 @@ import { connect } from 'react-redux'; 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: ```jsx @@ -102,7 +102,6 @@ import { userStateChanged } from './actions'; ... componentDidMount() { - // Listen for user auth state changes firebase.auth().onAuthStateChanged((user) => { // dispatch the imported action using the dispatch prop: @@ -158,7 +157,7 @@ previous state with a new one. ### 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 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: @@ -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 -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. > 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). 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 // src/App.js @@ -192,6 +191,7 @@ import firebase from 'react-native-firebase'; import { connect } from 'react-redux'; import UnauthenticatedStack from './screens/unauthenticated'; +import AuthenticatedStack from './screens/authenticated'; import { userStateChanged } from './actions'; class App extends Component { @@ -204,7 +204,6 @@ class App extends Component { } componentDidMount() { - // Listen for user auth state changes firebase.auth().onAuthStateChanged((user) => { this.props.dispatch(userStateChanged(user)); diff --git a/codorials/authentication-with-firebase/integrating-redux.md b/codorials/authentication-with-firebase/integrating-redux.md index 2b39a59a..58ba9631 100644 --- a/codorials/authentication-with-firebase/integrating-redux.md +++ b/codorials/authentication-with-firebase/integrating-redux.md @@ -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 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. -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. ## Installing Redux @@ -33,9 +33,11 @@ function reducer(state = {}, action) { 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 diff --git a/codorials/authentication-with-firebase/project-structure.md b/codorials/authentication-with-firebase/project-structure.md index 297d4f3f..9049758f 100644 --- a/codorials/authentication-with-firebase/project-structure.md +++ b/codorials/authentication-with-firebase/project-structure.md @@ -1,12 +1,13 @@ # 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 -an opinionated guide to how this might look, which will work across both Android & iOS. +Although it may seem trivial, having a good initial project structure ensures your code will be clean and reusable. + The following step gives an opinionated guide to how this might look, which will work across both Android & iOS. ## 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 -with basic styling. Rather than having two separate files, we're going to create a single file so both Android & iOS use it. +Every fresh React Native project a key file, an `index.js`, which currently renders a simple React component +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 project structure resembles the following: diff --git a/codorials/authentication-with-firebase/understanding-firebase-auth.md b/codorials/authentication-with-firebase/understanding-firebase-auth.md index 3245f35a..2cd20a1d 100644 --- a/codorials/authentication-with-firebase/understanding-firebase-auth.md +++ b/codorials/authentication-with-firebase/understanding-firebase-auth.md @@ -8,12 +8,12 @@ Luckily [react-native-firebase](https://rnfirebase.io) follows the Firebase web ## 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. 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: ![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 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. - 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. ## 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. 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: ```jsx