This commit is contained in:
Salakar 2017-03-02 12:50:09 +00:00
parent 6a9b54124a
commit 0bf4d74e59
9 changed files with 862 additions and 0 deletions

80
docs/api/analytics.md Normal file
View File

@ -0,0 +1,80 @@
# Analytics
Integrating Firebase analytics is super simple using RNFirebase. A number of methods are provided to help tailor analytics specifically for your
own app. The Firebase SDK includes a number of pre-set events which are automatically handled, and cannot be used with custom events:
```
'app_clear_data',
'app_uninstall',
'app_update',
'error',
'first_open',
'in_app_purchase',
'notification_dismiss',
'notification_foreground',
'notification_open',
'notification_receive',
'os_update',
'session_start',
'user_engagement',
```
#### `logEvent(event: string, params?: Object): void`
Log a custom event with optional params.
```javascript
firebase.analytics().logEvent('clicked_advert', { id: 1337 });
```
#### `setAnalyticsCollectionEnabled(enabled: boolean): void`
Sets whether analytics collection is enabled for this app on this device.
```javascript
firebase.analytics().setAnalyticsCollectionEnabled(false);
```
#### `setCurrentScreen(screenName: string, screenClassOverride?: string): void`
Sets the current screen name, which specifies the current visual context in your app.
> Whilst `screenClassOverride` is optional, it is recommended it is always sent as your current class name, for example on Android it will always show as 'MainActivity' if not specified.
```javascript
firebase.analytics().setCurrentScreen('user_profile');
```
#### `setMinimumSessionDuration(miliseconds: number): void`
Sets the minimum engagement time required before starting a session. The default value is 10000 (10 seconds).
```javascript
firebase.analytics().setMinimumSessionDuration(15000);
```
#### `setSessionTimeoutDuration(miliseconds: number): void`
Sets the duration of inactivity that terminates the current session. The default value is 1800000 (30 minutes).
```javascript
firebase.analytics().setSessionTimeoutDuration(900000);
```
#### `setUserId(id: string): void`
Gives a user a uniqiue identificaition.
```javascript
const id = firebase.auth().currentUser.uid;
firebase.analytics().setUserId(id);
```
#### `setUserProperty(name: string, value: string): void`
Sets a key/value pair of data on the current user.
```javascript
firebase.analytics().setUserProperty('nickname', 'foobar');
```

284
docs/api/authentication.md Normal file
View File

@ -0,0 +1,284 @@
# Authentication
RNFirebase handles authentication for us out of the box, both with email/password-based authentication and through oauth providers (with a separate library to handle oauth providers).
> Authentication requires Google Play services to be installed on Android.
## Auth
### Properties
##### `authenticated: boolean` - Returns the current Firebase authentication state.
##### `currentUser: User | null` - Returns the currently signed-in user (or null). See the [User](/docs/api/authentication.md#user) class documentation for further usage.
### Methods
#### [`onAuthStateChanged(event: Function): Function`](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#onAuthStateChanged)
Listen for changes in the users auth state (logging in and out). This method returns a unsubscribe function to stop listening to events. Always ensure you unsubscribe from the listener when no longer needed to prevent updates to components no longer in use.
```javascript
class Example extends React.Component {
constructor() {
super();
this.unsubscribe = null;
}
componentDidMount() {
this.unsubscribe = firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in.
}
});
}
componentWillUnmount() {
if (this.unsubscribe) {
this.unsubscribe();
}
}
}
```
#### [`createUserWithEmailAndPassword(email: string, password: string): Promise`](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#createUserWithEmailAndPassword)
We can create a user by calling the `createUserWithEmailAndPassword()` function.
The method accepts two parameters, an email and a password.
```javascript
firebase.auth().createUserWithEmailAndPassword('foo@bar.com', '123456')
.then((user) => {
console.log('user created', user)
})
.catch((err) => {
console.error('An error occurred', err);
});
```
#### [`signInWithEmailAndPassword(email: string, password: string): Promise`](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signInWithEmailAndPassword)
To sign a user in with their email and password, use the `signInWithEmailAndPassword()` function.
It accepts two parameters, the user's email and password:
```javascript
firebase.auth().signInWithEmailAndPassword('foo@bar.com', '123456')
.then((user) => {
console.log('User successfully logged in', user)
})
.catch((err) => {
console.error('User signin error', err);
});
```
#### [`signInAnonymously(): Promise`](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signInAnonymously)
Sign an anonymous user. If the user has already signed in, that user will be returned.
```javascript
firebase.auth().signInAnonymously()
.then((user) => {
console.log('Anonymous user successfully logged in', user)
})
.catch((err) => {
console.error('Anonymous user signin error', err);
});
```
#### [`signInWithCredential(credential: Object): Promise`](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signInWithCredential)
Sign in the user with a 3rd party credential provider. `credential` requires the following properties:
```javascript
{
provider: string,
token: string,
secret: string
}
```
```javascript
const credential = {
provider: 'facebook.com',
token: '12345',
secret: '6789',
};
firebase.auth().signInWithCredential(credential)
.then((user) => {
console.log('User successfully signed in', user)
})
.catch((err) => {
console.error('User signin error', err);
});
```
#### [`signInWithCustomToken(token: string): Promise`](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signInWithCustomToken)
Sign a user in with a self-signed [JWT](https://jwt.io) token.
To sign a user using a self-signed custom token, use the `signInWithCustomToken()` function. It accepts one parameter, the custom token:
```javascript
firebase.auth().signInWithCustomToken('12345')
.then((user) => {
console.log('User successfully logged in', user)
})
.catch((err) => {
console.error('User signin error', err);
});
```
#### [`sendPasswordResetEmail(email: string): Promise`](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#sendPasswordResetEmail)
Sends a password reset email to the given email address. Unlike the web SDK, the email will contain a password reset link rather than a code.
```javascript
firebase.auth().sendPasswordResetEmail('foo@bar.com')
.then(() => {
console.log('Password reset email sent');
})
.catch((error) => {
console.error('Unable send password reset email', error);
});
```
#### [`signOut(): Promise`](https://firebase.google.com/docs/reference/js/firebase.auth.Auth#confirmPasswordReset)
Completes the password reset process, given a confirmation code and new password.
```javascript
firebase.auth().signOut()
.then(() => {
console.log('User signed out successfully');
})
.catch();
```
## User
User class returned from `firebase.auth().currentUser`.
### Properties
##### `displayName: string | null` - The user's display name (if available).
##### `email: string | null` - The user's email address (if available).
##### `emailVerified: boolean` - True if the user's email address has been verified.
##### `isAnonymous: boolean`
##### `photoURL: string | null` - The URL of the user's profile picture (if available).
##### `providerData: Object | null` - Additional provider-specific information about the user.
##### `providerId: string | null` - The authentication provider ID for the current user. For example, 'facebook.com', or 'google.com'.
##### `uid: string` - The user's unique ID.
### Methods
#### [`delete(): Promise`](https://firebase.google.com/docs/reference/js/firebase.User#delete)
Delete the current user.
```javascript
firebase.auth().currentUser
.delete()
.then()
.catch();
```
#### [`getToken(): Promise`](https://firebase.google.com/docs/reference/js/firebase.User#getToken)
Returns the users authentication token.
```javascript
firebase.auth().currentUser
.getToken()
.then((token) => {})
.catch();
```
#### [`reauthenticate(credential: Object): Promise`](https://firebase.google.com/docs/reference/js/firebase.User#reauthenticate)
Reauthenticate the current user with credentials:
```javascript
{
provider: string,
token: string,
secret: string
}
```
```javascript
const credentials = {
provider: 'facebook.com',
token: '12345',
secret: '6789',
};
firebase.auth().currentUser
.reauthenticate(credentials)
.then()
.catch();
```
#### [`reload(): Promise`](https://firebase.google.com/docs/reference/js/firebase.User#reload)
Refreshes the current user.
```javascript
firebase.auth().currentUser
.reload()
.then((user) => {})
.catch();
```
#### [`sendEmailVerification(): Promise`](https://firebase.google.com/docs/reference/js/firebase.User#sendEmailVerification)
Sends a verification email to a user. This will Promise reject is the user is anonymous.
```javascript
firebase.auth().currentUser
.sendEmailVerification()
.then()
.catch();
```
#### [updateEmail(email: string)](https://firebase.google.com/docs/reference/js/firebase.User#updateEmail)
Updates the user's email address. See Firebase docs for more information on security & email validation. This will Promise reject is the user is anonymous.
```javascript
firebase.auth().updateUserEmail('foo@bar.com')
.then()
.catch();
```
#### [updatePassword(password: string)](https://firebase.google.com/docs/reference/js/firebase.User#updatePassword)
Important: this is a security sensitive operation that requires the user to have recently signed in. If this requirement isn't met, ask the user to authenticate again and then call firebase.User#reauthenticate. This will Promise reject is the user is anonymous.
```javascript
firebase.auth().updatePassword('foobar1234')
.then()
.catch();
```
#### [updateProfile(profile: Object)](https://firebase.google.com/docs/reference/js/firebase.User#updateProfile)
Updates a user's profile data. Profile data should be an object of fields to update:
```javascript
{
displayName: string,
photoURL: string,
}
```
```javascript
firebase.auth()
.updateProfile({
displayName: 'Ari Lerner'
})
.then()
.catch();
```

194
docs/api/database.md Normal file
View File

@ -0,0 +1,194 @@
# Realtime Database
RNFirebase mimics the [Web Firebase SDK Realtime Database](https://firebase.google.com/docs/database/web/read-and-write), whilst
providing support for devices in low/no data connection state.
All real time Database operations are accessed via `database()`.
Basic read example:
```javascript
firebase.database()
.ref('posts')
.on('value', (snapshot) => {
const value = snapshot.val();
});
```
Basic write example:
```javascript
firebase.database()
.ref('posts/1234')
.set({
title: 'My awesome post',
content: 'Some awesome content',
});
```
## Unmounted components
Listening to database updates on unmounted components will trigger a warning:
> Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.
It is important to always unsubscribe the reference from receiving new updates once the component is no longer in use.
This can be achived easily using [Reacts Component Lifecycle](https://facebook.github.io/react/docs/react-component.html#the-component-lifecycle) events:
Always ensure the handler function provided is of the same reference so RNFirebase can unsubscribe the ref listener.
```javascript
class MyComponent extends Component {
constructor() {
super();
this.ref = null;
}
// On mount, subscribe to ref updates
componentDidMount() {
this.ref = firebase.database().ref('posts/1234');
this.ref.on('value', this.handlePostUpdate);
}
// On unmount, ensure we no longer listen for updates
componentWillUnmount() {
if (this.ref) {
this.ref.off('value', this.handlePostUpdate);
}
}
// Bind the method only once to keep the same reference
handlePostUpdate = (snapshot) => {
console.log('Post Content', snapshot.val());
}
render() {
return null;
}
}
```
## Usage in offline environments
### Reading data
Firstack allows the database instance to [persist on disk](https://firebase.google.com/docs/database/android/offline-capabilities) if enabled.
To enable database persistence, pass the configuration option `persistence` before calls are made:
```javascript
const configurationOptions = {
persistence: true
};
const firebase = new RNFirebase(configurationOptions);
```
Any subsequent calls to Firebase stores the data for the ref on disk.
### Writing data
Out of the box, Firebase has great support for writing operations in offline environments. Calling a write command whilst offline
will always trigger any subscribed refs with new data. Once the device reconnects to Firebase, it will be synced with the server.
The following todo code snippet will work in both online and offline environments:
```javascript
// Assume the todos are stored as an object value on Firebase as:
// { name: string, complete: boolean }
class ToDos extends Component {
constructor() {
super();
this.ref = null;
this.listView = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.state = {
todos: this.listView.cloneWithRows({}),
};
// Keep a local reference of the TODO items
this.todos = {};
}
// Load the Todos on mount
componentDidMount() {
this.ref = firebase.database().ref('users/1234/todos');
this.ref.on('value', this.handleToDoUpdate);
}
// Unsubscribe from the todos on unmount
componentWillUnmount() {
if (this.ref) {
this.ref.off('value', this.handleToDoUpdate);
}
}
// Handle ToDo updates
handleToDoUpdate = (snapshot) => {
this.todos = snapshot.val() || {};
this.setState({
todos: this.listView.cloneWithRows(this.todos),
});
}
// Add a new ToDo onto Firebase
// If offline, this will still trigger an update to handleToDoUpdate
addToDo() {
firebase.database()
.ref('users/1234/todos')
.set({
...this.todos, {
name: 'Yet another todo...',
complete: false,
},
});
}
// Render a ToDo row
renderToDo(todo) {
// Dont render the todo if its complete
if (todo.complete) {
return null;
}
return (
<View>
<Text>{todo.name}</Text>
</View>
);
}
// Render the list of ToDos with a Button
render() {
return (
<View>
<ListView
dataSource={this.state.todos}
renderRow={(...args) => this.renderToDo(...args)}
/>
<Button
title={'Add ToDo'}
onPress={() => this.addToDo}
/>
<View>
);
}
```
#### Differences between `.on` & `.once`
With persistence enabled, any calls to a ref with `.once` will always read the data from disk and not contact the server.
On behavious differently, by first checking for a connection and if none exists returns the persisted data. If it successfully connects
to the server, the new data will be returned and the disk data will be updated.
The database refs has a `keepSynced()` function to tell the RNFirebase library to keep the data at the `ref` in sync.
```javascript
const ref = firebase.database
.ref('chat-messages')
.child('roomId');
ref.keepSynced(true);
```

View File

@ -0,0 +1 @@
# Remote Config

91
docs/api/storage.md Normal file
View File

@ -0,0 +1,91 @@
# Storage
RNFirebase mimics the [Web Firebase SDK Storage](https://firebase.google.com/docs/storage/web/start), whilst
providing some iOS and Android specific functionality.
All Storage operations are accessed via `storage()`.
## Uploading files
### Simple
```javascript
firebase.storage()
.ref('/files/1234')
.putFile('/path/to/file/1234')
.then(uploadedFile => {
//success
})
.catch(err => {
//Error
});
```
### Listen to upload state
```javascript
const unsubscribe = firebase.storage()
.ref('/files/1234')
.putFile('/path/to/file/1234')
.on('state_changed', snapshot => {
//Current upload state
}, err => {
//Error
unsubscribe();
}, uploadedFile => {
//Success
unsubscribe();
});
```
## Downloading files
### Simple
```javascript
firebase.storage()
.ref('/files/1234')
.downloadFile('/path/to/save/file')
.then(downloadedFile => {
//success
})
.catch(err => {
//Error
});
```
### Listen to download state
```javascript
const unsubscribe = firebase.storage()
.ref('/files/1234')
.downloadFile('/path/to/save/file')
.on('state_changed', snapshot => {
//Current download state
}, err => {
//Error
unsubscribe();
}, downloadedFile => {
//Success
unsubscribe();
});
```
## TODO
There are a few methods which have not yet been implemented for Storage:
### Reference
- put()
- putString()
### UploadTask
- cancel()
- pause()
- resume()
### DownloadTask
- cancel()
- pause()
- resume()

89
docs/firebase-setup.md Normal file
View File

@ -0,0 +1,89 @@
# Firebase Setup
The RNFirebase library is intended on making it easy to work with [Firebase](https://firebase.google.com/) and provides a small native shim to the Firebase native code.
To add Firebase to your project, make sure to create a project in the [Firebase console](https://firebase.google.com/console)
![Create a new project](http://d.pr/i/17cJ2.png)
Each platform uses a different setup method after creating the project.
## iOS
After creating a Firebase project, click on the [Add Firebase to your iOS app](http://d.pr/i/3sEL.png) and follow the steps from there to add the configuration file. You do _not_ need to set up a cocoapods project (this is already done through RNFirebase). Make sure not to forget the `Copy Files` phase in iOS.
[Download the Firebase config file](https://support.google.com/firebase/answer/7015592) and place it in your app directory next to your app source code:
![GoogleService-Info.plist](http://d.pr/i/1eGev.png)
Once you download the configuration file, make sure you place it in the root of your Xcode project. Every different Bundle ID (aka, even different project variants needs their own configuration file).
Lastly, due to some dependencies requirements, RNFirebase supports iOS versions 8.0 and up. Make sure to update the minimum version of your iOS app to `8.0`.
## Android
There are several ways to setup Firebase on Android. The _easiest_ way is to pass the configuration settings in JavaScript. In that way, there is no setup for the native platform.
### google-services.json setup
If you prefer to include the default settings in the source of your app, download the `google-services.json` file provided by Firebase in the _Add Firebase to Android_ platform menu in your Firebase configuration console.
Next you'll have to add the google-services gradle plugin in order to parse it.
Add the google-services gradle plugin as a dependency in the *project* level build.gradle
`android/build.gradle`
```java
buildscript {
// ...
dependencies {
// ...
classpath 'com.google.gms:google-services:3.0.0'
}
}
```
In your app build.gradle file, add the gradle plugin at the VERY BOTTOM of the file (below all dependencies)
`android/app/build.gradle`
```java
apply plugin: 'com.google.gms.google-services'
```
## Usage
After creating a Firebase project and installing the library, we can use it in our project by importing the library in our JavaScript:
```javascript
import RNFirebase from 'react-native-firebase'
```
We need to tell the Firebase library we want to _configure_ the project. RNFirebase provides a way to configure both the native and the JavaScript side of the project at the same time with a single command:
```javascript
const firebase = new RNFirebase();
```
We can pass _custom_ options by passing an object with configuration options. The configuration object will be generated first by the native configuration object, if set and then will be overridden if passed in JS. That is, all of the following key/value pairs are optional if the native configuration is set.
| option | type | Default Value | Description |
|----------------|----------|-------------------------|----------------------------------------|
| debug | bool | false | When set to true, RNFirebase will log messages to the console and fire `debug` events we can listen to in `js` |
| persistence | bool | false | When set to true, database persistence will be enabled. |
| bundleID | string | Default from app `[NSBundle mainBundle]` | The bundle ID for the app to be bundled with |
| googleAppID | string | "" | The Google App ID that is used to uniquely identify an instance of an app. |
| databaseURL | string | "" | The database root (i.e. https://my-app.firebaseio.com) |
| deepLinkURLScheme | string | "" | URL scheme to set up durable deep link service |
| storageBucket | string | "" | The Google Cloud storage bucket name |
| androidClientID | string | "" | The Android client ID used in Google AppInvite when an iOS app has it's android version |
| GCMSenderID | string | "" | The Project number from the Google Developer's console used to configure Google Cloud Messaging |
| trackingID | string | "" | The tracking ID for Google Analytics |
| clientID | string | "" | The OAuth2 client ID for iOS application used to authenticate Google Users for signing in with Google |
| APIKey | string | "" | The secret iOS API key used for authenticating requests from our app |
For instance:
```javascript
const configurationOptions = {
debug: true
};
const firebase = new RNFirebase(configurationOptions);
firebase.on('debug', msg => console.log('Received debug message', msg))
```

View File

@ -0,0 +1,55 @@
# Android Installation
The simplest way of installing on Android is to use React Native linker:
```
react-native link react-native-firebase
```
## Manually
To install `react-native-firebase` manually in our project, we'll need to import the package from `io.invertase.firebase` in our project's `android/app/src/main/java/com/[app name]/MainApplication.java` and list it as a package for ReactNative in the `getPackages()` function:
```java
package com.youcompany.application;
// ...
import io.invertase.firebase.RNFirebasePackage;
// ...
public class MainApplication extends Application implements ReactApplication {
// ...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNFirebasePackage() // <-- Add this line
);
}
};
// ...
}
```
We'll also need to list it in our `android/app/build.gradle` file as a dependency that we want React Native to compile. In the `dependencies` listing, add the `compile` line:
```java
dependencies {
compile project(':react-native-firebase')
}
```
Add to `AndroidManifest.xml` file
```diff
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
+ <service android:name="io.invertase.firebase.RNFirebaseMessagingService">
+ <intent-filter>
+ <action android:name="com.google.firebase.MESSAGING_EVENT"/>
+ </intent-filter>
+ </service>
+ <service android:name="io.invertase.firebase.RNFirebaseInstanceIdService" android:exported="false">
+ <intent-filter>
+ <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
+ </intent-filter>
+ </service>
```

67
docs/installation.ios.md Normal file
View File

@ -0,0 +1,67 @@
#iOS Installation
If you don't want to use cocoapods, you don't need to use it! Just make sure you link the Firebase libraries in your project manually. For more information, check out the relevant Firebase docs at [https://firebase.google.com/docs/ios/setup#frameworks](https://firebase.google.com/docs/ios/setup#frameworks).
## cocoapods
Unfortunately, due to AppStore restrictions, we currently do _not_ package Firebase libraries in with Firebase. However, the good news is we've automated the process (with many thanks to the Auth0 team for inspiration) of setting up with cocoapods. This will happen automatically upon linking the package with `react-native-cli`.
**Remember to use the `ios/[YOUR APP NAME].xcworkspace` instead of the `ios/[YOUR APP NAME].xcproj` file from now on**.
We need to link the package with our development packaging. We have two options to handle linking:
#### Automatically with react-native-cli
React native ships with a `link` command that can be used to link the projects together, which can help automate the process of linking our package environments.
```bash
react-native link react-native-firebase
```
Update the newly installed pods once the linking is done:
```bash
cd ios && pod update --verbose
```
#### Manually
If you prefer not to use `react-native link`, we can manually link the package together with the following steps, after `npm install`:
**A.** In XCode, right click on `Libraries` and find the `Add Files to [project name]`.
![Add library to project](http://d.pr/i/2gEH.png)
**B.** Add the `node_modules/react-native-firebase/ios/Firebase.xcodeproj`
![Firebase.xcodeproj in Libraries listing](http://d.pr/i/19ktP.png)
**C.** Ensure that the `Build Settings` of the `RNFirebase.xcodeproj` project is ticked to _All_ and it's `Header Search Paths` include both of the following paths _and_ are set to _recursive_:
1. `$(SRCROOT)/../../react-native/React`
2. `$(SRCROOT)/../node_modules/react-native/React`
3. `${PROJECT_DIR}/../../../ios/Pods`
![Recursive paths](http://d.pr/i/1hAr1.png)
**D.** Setting up cocoapods
Since we're dependent upon cocoapods (or at least the Firebase libraries being available at the root project -- i.e. your application), we have to make them available for RNFirebase to find them.
Using cocoapods is the easiest way to get started with this linking. Add or update a `Podfile` at `ios/Podfile` in your app with the following:
```ruby
source 'https://github.com/CocoaPods/Specs.git'
[
'Firebase/Core',
'Firebase/Auth',
'Firebase/Storage',
'Firebase/Database',
'Firebase/RemoteConfig',
'Firebase/Messaging'
].each do |lib|
pod lib
end
```
Then you can run `(cd ios && pod install)` to get the pods opened. If you do use this route, remember to use the `.xcworkspace` file.

1
docs/redux.md Normal file
View File

@ -0,0 +1 @@