[docs] version docs

This commit is contained in:
Salakar
2017-08-11 17:20:10 +01:00
parent 8627d5d87f
commit 70b6983583
26 changed files with 2854 additions and 13 deletions

3
docs/_navbar.md Normal file
View File

@@ -0,0 +1,3 @@
- <div style="padding: 8px; border-radius: 3px; border: 1px solid #e3e3e3;"><b>Version:</b> v3.x.x</div>
- [v2.x.x](/v2/)

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>react-native-firebase - A react native firebase library supporting both android and ios native firebase SDK's</title>
<title>React Native Firebase - A react native firebase library supporting both android and ios native firebase SDK's</title>
<meta name="description" content="A react native firebase library supporting both android and ios native firebase SDK's">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="shortcut icon" type="image/png" href="https://camo.githubusercontent.com/6c827e5a0bb91259f82a1f4923ab7efa4891b119/687474703a2f2f692e696d6775722e636f6d2f303158514c30782e706e67"/>
@@ -12,28 +12,30 @@
</body>
<script>
window.$docsify = {
name: 'react-native-firebase',
name: 'React Native Firebase - Documentation',
repo: 'https://github.com/invertase/react-native-firebase',
loadSidebar: true,
loadNavbar: true,
mergeNavbar: true,
search: 'auto',
themeColor: '#f5820b',
subMaxLevel: 3,
maxLevel: 4,
ga: 'UA-98196653-1',
formatUpdated: '{DD}/{MM}/{YYYY} {HH}:{mm}',
plugins: [
function (hook) {
var footer = [
'<hr/>',
'<footer>',
`<span>Caught a mistake or want to contribute to the documentation? <a href="https://github.com/invertase/react-native-firebase/tree/master/docs" target="_blank">Edit documentation on Github!</a>.</span>`,
'</footer>'
].join('');
hook.afterEach(function (html) {
return html + footer
function(hook, vm) {
hook.beforeEach(function (html) {
var url = 'https://github.com/invertase/react-native-firebase/blob/master/docs/' + vm.route.file;
var editHtml = '[:memo: Edit](' + url + ')\n';
return editHtml
+ html
+ '\n----\n'
+ '<b>Last updated</b>: {docsify-updated} '
+ editHtml
})
}
]
],
}
</script>
<script>

66
docs/v2/README.md Normal file
View File

@@ -0,0 +1,66 @@
<h1 align="center">
<img src="https://camo.githubusercontent.com/6c827e5a0bb91259f82a1f4923ab7efa4891b119/687474703a2f2f692e696d6775722e636f6d2f303158514c30782e706e67"/><br>
React Native Firebase
</h1>
<div style="text-align: center;">
[![npm version](https://img.shields.io/npm/v/react-native-firebase.svg?style=flat-square)](https://www.npmjs.com/package/react-native-firebase)
[![NPM downloads](https://img.shields.io/npm/dm/react-native-firebase.svg?style=flat-square)](https://www.npmjs.com/package/react-native-firebase)
[![Package Quality](https://npm.packagequality.com/shield/react-native-firebase.svg?style=flat-square)](http://packagequality.com/#?package=react-native-firebase)
[![License](https://img.shields.io/npm/l/react-native-firebase.svg?style=flat-square)](/LICENSE)
[![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg?style=flat-square)](https://discord.gg/t6bdqMs)
[![Chat](https://img.shields.io/badge/chat-on%20gitter-a0e7a0.svg?style=flat-square)](https://gitter.im/invertase/react-native-firebase)
[![Donate](https://img.shields.io/badge/Donate-Patreon-green.svg?style=flat-square)](https://www.patreon.com/invertase)
</div>
---
RNFirebase is a _light-weight_ layer sitting on-top of the native Firebase libraries for both iOS and Android which mirrors the Firebase Web SDK as closely as possible.
Although the [Firebase Web SDK](https://www.npmjs.com/package/firebase) library will work with React Native, it is mainly built for the web.
RNFirebase provides a JavaScript bridge to the native Firebase SDKs for both iOS and Android therefore Firebase will run on the native thread, allowing the rest of your app to run on the [JS thread](https://facebook.github.io/react-native/docs/performance.html#javascript-frame-rate). The Firebase Web SDK also runs on the JS thread, therefore potentially affecting the frame rate causing jank with animations, touch events etc.
The native SDKs also allow us to hook into device sdk's which are not possible with the web SDK, for example crash reporting, offline realtime database support, analyics and more!
All in all, RNFirebase provides much faster performance (~2x) over the web SDK and provides device sdk's not found in the web sdk (see the feature table below).
---
## Supported Firebase Features
> The Web SDK column indicates what modules from the Firebase Web SDK are usable within React Native.
| Firebase Features | v1 | v2 | Web SDK |
| ---------------------- | :---: | :---: | :---: |
| AdMob | ❌ | ✅ | ❌ |
| Analytics             | ✅ | ✅ | ❌ |
| App Indexing           | ❌ | ❌ | ❌ |
| Authentication | ✅ | ✅ | ✅ |
| Cloud Messaging (FCM) | ✅ | ✅ | ❌ |
| Crash Reporting | ✅ | ✅ | ❌ |
| Dynamic Links | ❌ | ❌ | ❌ |
| Invites | ❌ | ❌ | ❌ |
| Performance Monitoring | ✅ | ✅ | ❌ |
| Realtime Database | ✅ | ✅ | ✅ |
| - Offline Persistence | ✅ | ✅ | ❌ |
| - Transactions | ✅ | ✅ | ✅ |
| Remote Config | ✅ | ✅ | ❌ |
| Storage | ✅ | ✅ | ❌ |
---
### Supported versions - React Native / Firebase
> The table below shows the supported version of `react-native-firebase` for different React Native versions
| | v0.36 - v0.39 | v0.40 - v0.46 | v0.47 +
| ------------------------------- | :---: | :---: | :---: |
| react-native-firebase | 1.X.X | 2.X.X | 2.1.X |
> The table below shows the minimum supported versions of the Firebase SDKs for each version of `react-native-firebase`
| | v1 | v2 |
| ---------------------- | :---: | :---: |
| Firebase Android SDK | 10.2.0+ | 11.0.0 + |
| Firebase iOS SDK | 3.15.0+ | 4.0.0 + |

3
docs/v2/_navbar.md Normal file
View File

@@ -0,0 +1,3 @@
- <div style="padding: 8px; border-radius: 3px; border: 1px solid #e3e3e3;"><b>Version:</b> v2.x.x</div>
- [v3.x.x](/)

34
docs/v2/_sidebar.md Normal file
View File

@@ -0,0 +1,34 @@
- Getting started
- [Initial setup](/initial-setup)
- [Installation - iOS](/installation-ios)
- [Installation - Android](/installation-android)
- [Usage](/usage)
- [Migration Guide](/migration-guide)
- Contributing
- [Guidelines](/contributing/guidelines)
- [Testing](/contributing/testing)
- Core
- [App](/core/app)
- [Firebase](/core/firebase)
- Modules
- [Admob](/modules/admob)
- [Analytics](/modules/analytics)
- [Authentication](/modules/authentication)
- [Cloud Messaging](/modules/cloud-messaging)
- [Crash Reporting](/modules/crash)
- [Database](/modules/database)
- [Remote Config](/modules/config)
- [Storage](/modules/storage)
- [Transactions](/modules/transactions)
- [Performance Monitoring](/modules/perf)
- Other
- [Usage with Redux](/redux)
- [Project Board](https://github.com/invertase/react-native-firebase/projects)
- [FAQs / Troubleshooting](/faqs)
- [Examples](https://github.com/invertase/react-native-firebase-examples)
- [Chat](https://discord.gg/t6bdqMs)
- [Gitter](https://gitter.im/invertase/react-native-firebase)

View File

@@ -0,0 +1,5 @@
# Guidelines
We welcome any contribution to the repository. Please ensure your changes to the JavaScript code follow the styling guides controlled by ESlint. Changes to native code should be kept clean and follow the standard of existing code.
Changes to existing code should ensure all relevant tests on the test app pass. Any new features should have new tests created and ensure all existing tests pass.

View File

@@ -0,0 +1,330 @@
# Testing
Currently due to the blackbox Firebase enviroment, we have found the best way to test the library is to directly test against the library using a live Firebase project. As some modules also work with the offical web SDK, we can directly compare the results against our own library. This is however restrictive as it doesn't directly test the native code/modules. Plans are in place to overhaul the entire testing setup.
## Running the test app
For convenience all of the required NPM scripts are packaged with the main library to run the test app.
### Step 1 - Fork & Clone
```bash
git clone git@github.com:<username>/react-native-firebase.git
```
### Step 2 - Install dependencies
```bash
npm run tests-npm-install
```
### Step 3 - Install [WML](https://github.com/wix/wml)
WML is a library which copies files & directories to a location. This allows us to copy any changes from the library directly into the tests app, so we can quickly test changes.
```bash
npm install -g wml
```
### Step 4 - Start the watcher
```bash
npm run tests-watch-init
npm run tests-watch-start
```
### Step 5 - Start the app
```bash
npm run tests-packager
```
#### Android
Open the `tests/android` directory from Android Studio and allow Gradle to sync. Now run the app on an emulator/device.
#### iOS
First install the Pods:
```
npm run tests-pod-install
```
Open the `tests/ios/ReactNativeFirebaseDemo.xcworkspace` file in XCode and build for your preffered device or simulator.
## Tests
Tests are bootstrapped and ran when the `play` button is pressed. The status of each test suite and individual test will update as and when a test has completed or errored.
### Running tests
Tests can be run by pressing the play button in the toolbar of the app. Test can be run individually, by suite, or all at once.
![Test suite Android](https://github.com/invertase/react-native-firebase/blob/master/tests/docs/assets/test-suite-screenshot-android.png?raw=true)
### Adding test
To add tests to an existing test suite, you need to pass a function to `addTests`.
#### Synchronous tests
Synchronous tests are created by passing a function to `it`. The next test is run immediately after the last line is executed.
```javascript
testSuite.addTests(({ describe, it }) => {
describe('synchronous test', () => {
it('does something correctly', () => {
});
});
});
```
#### Asynchronous tests
Tests can be asynchronous if they return a promise. The test suite waits for the promise to resolve before executing the next test.
```javascript
testSuite.addTests(({ describe, it }) => {
describe('async successful test', () => {
it('does something correctly', () => {
return new Promise((resolve, reject) => {
// ...
resolve();
});
});
});
});
```
Asynchronous tests can also be created using the `async` function syntax:
```javascript
testSuite.addTests(({ describe, it }) => {
describe('async successful test', () => {
it('does something correctly', async () => {
// ...
await somethingAsynchronous();
});
});
});
```
> When rejecting, always ensure a valid [JavaScript Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) is provided.
### Creating a new test suite
A test suite groups together test categories under the same Firebase feature. e.g. *Realtime Database* tests.
To add a new test suite:
1. Create a new directory within `src/tests`.
2. Create an `index.js` file.
In this file, you need to create an instance of `TestSuite` - see [TestSuite constructor](#testsuite-constructor).
```javascript
import TestSuite from 'lib/TestSuite';
const MyNewSuite = new TestSuite('Realtime Database Storage', 'Upload/Download storage tests');
export default MyNewSuite;
```
3. `addTests` is then used as many times as is necessary to add tests to the test suite, accepting a function that defines one or more tests.
4. The test suite must then be imported into `src/tests/index.js` and added to `testSuiteInstances` in order for it to be included in the list of test suites available to run in the app.
## TestSuite API
### TestSuite Constructor
The TestSuite constructor accepts 3 arguments:
- **name**: String containing the name of the test suite. e.g. 'Realtime Storage'
- **description**: String containing description of the test suite
- **firebase**: This is the object exported from `src/firebase` and contains both the native and web firebase instances.
```javascript
import firebase from '../firebase';
new TestSuite('Realtime Database Storage', 'firebase.database()', firebase);
```
### Test Definition
#### describe()
The `describe()` function takes 2 - 3 arguments:
- **description**: String describing the context or target of all the tests defined in `testDefinitions`
- **options**: (Optional) object of options:
* **focus**: Boolean marking all the tests defined in `testDefinitions` (and any others marked as focused) as the only one(s) that should run
* **pending**: Boolean marking all the tests defined in `testDefinitions` as excluded from running in the test suite
- **testDefinitions**: Function that defines 1 or more tests by calling `it`, `xit` or `fit`
```javascript
function testCategory({ describe }) {
describe('a feature', () => {
it('does something synchronously', () => {
});
});
}
export default testCategory;
```
`describe()` statements can be arbitrarily nested.
#### context()
`context()` is an alias for `describe()` provided as syntactical sugar. `xcontext()` and `fcontext()` work similar to `xdescribe()` and `fdescribe()`, respectively.
#### it()
The `it()` function takes 2 - 3 arguments:
- **description**: String describing the test defined in `testDefinition`
- **options**: (Optional) object of options:
* **focus**: Boolean marking the test defined in `testDefinition` (and any others marked as focused) as the only one(s) that should run
* **pending**: Boolean marking the test defined in `testDefinition` as excluded from running in the test suite
* **timeout**: Time in milliseconds a test is allowed to execute before it's considered to have timed out. Default is 5000ms (5 seconds).
- **testDefinition**: Function that defines a test with one or more assertions. Can be a synchronous or asynchronous function. Functions that return a promise cause the test environment to wait for the promise to be resolved before proceding to the next test.
```javascript
it('does something synchronously', () => {
});
it('does something asynchronously', async () => {
});
it('does something else asynchronously', () => {
return new Promise(/* ... */);
});
```
`it()` statements can *not* be nested.
#### xdescribe() & xit()
##### Pending Tests
You can mark all tests within a `describe` statement as pending by using the `xdescribe` function instead. The test will appear greyed out and will not be run as part of the test suite.
You can mark a single test as pending by using `xit` as you would `it`.
Tests should only be marked as pending temporarily, and should not normally be committed to the test suite unless they are fully implemented.
#### fdescribe() & fit()
##### Focused Tests
You can mark all tests within a `describe` statement as focused by using the `fdescribe` function instead. Tests that are focused will be the only ones that appear and run in the test suite until all tests are removed from being focused. This is useful for running and working on a few tests at a time.
You can mark a single test as focused by using `fit` as you would `it`.
#### Test Assertions
The assertion library Should.js is used in the tests. The complete list of available assertions is available in the [Should.js documentation](https://shouldjs.github.io).
#### Lifecycle methods
Four lifecycle methods are provided for each test context:
- **before** - Run once, before the current test context executes
- **beforeEach** - Run before every test in the current test context
- **after** - Run once, after the current test context has finished executing
- **afterEach** - Run after every test in the current test context
A new test context is created when the test suite encounters any of `describe`, `xdescribe`, `fdescribe`, `context`, `xcontext` or `fcontext`, and close again when it reaches the end of the block. Test contexts can be nested and lifecycle hooks set for parent contexts apply for all descendents.
Each lifecycle hook accepts either a synchronous function, a function that returns a promise or an `async` function.
```javascript
function testCategory({ before, beforeEach, afterEach, after }) {
before(() => console.log('Before all tests start.'));
beforeEach(() => console.log('Before every test starts.'));
describe('sync successful test', function() {
// ...
});
afterEach(() => console.log('After each test starts.'));
after(() => console.log('After all tests are complete, with success or error.'));
}
```
An optional hash of options can also be passed as the first argument, defining one or more of the following values:
* **timeout**: Time in milliseconds a hook is allowed to execute before it's considered to have timed out. Default is 5000ms (5 seconds).
#### Accessing Firebase
`react-native-firebase` is available `firebase.native`:
```javascript
function testCategory({ describe, firebase }) {
describe('sync successful test', 'category', function() {
firebase.native.database();
});
}
```
If you need to access the web API for Firebase to compare with the functionality of `react-native-firebase`, you can access it on `firebase.web`.
> All tests should be written in terms of `react-native-firebase`'s behaviour and should **not** include direct comparisons with the web API. It's available for reference, only.
## Development Notes
> JavaScript changes do **not** require restarting the React Native packager to take effect
> Java changes will need to be rebuilt in Android Studio
> Objective-C changes need to be rebuilt in Xcode
### Debugging or viewing internals of the test suite
`react-native-firebase/tests` is compatible with [react-native-debugger](https://github.com/jhen0409/react-native-debugger) and is the recommended way to view the internal state of the test suite for development or troubleshooting.
It allows you to view state and prop values of the React component tree, view the actions and contents of the Redux store and view and interact with the debugging console.
Make sure **Remote JS Debugging** when running the application and close any chrome debugging windows that appear and start React Native Debugger.
### Running the internal tests
`react-native-firebase-tests` has its own tests to verify the testing framework is working as expected. These are run from the command line:
```bash
npm run internal-tests
```
## Troubleshooting
### Invalid React.podspec file: no implicit conversion of nil into String
This error occurs if you are using ruby version 2.1.2. Upgrade your version of ruby and try again.
### Unable to resolve module ../../../node_modules/react-native/packager/...
Run the packager separately, clearing the cache:
```bash
npm start -- --reset-cache
```

34
docs/v2/core/app.md Normal file
View File

@@ -0,0 +1,34 @@
# App - firebase.app(): FirebaseApp
RNFirebase supports both initializing apps natively and also via js code over the RN bridge.
Apps initialized natively are available immediately at app runtime, there is no need to call `initializeApp` for them.
For example, to access the default app initialized via the `Google-Services` `plist` or `json` file:
```javascipt
import firebase from 'react-native-firebase';
const defaultApp = firebase.app();
defaultApp.database().ref('foobar').once('value', (snapshot) => {
// snapshot from default app
});
// get the default app name/options that were initialized natively
console.log("name", defaultApp.name);
console.log("apiKey", defaultApp.options.apiKey);
console.log("applicationId", defaultApp.options.applicationId);
console.log("databaseUrl", defaultApp.options.databaseUrl);
console.log("messagingSenderId", defaultApp.options.messagingSenderId);
console.log("projectId", defaultApp.options.projectId);
console.log("storageBucket", defaultApp.options.projectId);
```
TODO api ref docs:
- name: String
- options: Object
- delete(): Promise

10
docs/v2/core/firebase.md Normal file
View File

@@ -0,0 +1,10 @@
# Firebase
TODO api ref docs:
- apps(): Array<FirebaseApp>
- app(): FirebaseApp
- initializeApp(): FirebaseApp
- setLogLevel()
- SDK_VERSION: String
- googleApiAvailability: Object

103
docs/v2/faqs.md Normal file
View File

@@ -0,0 +1,103 @@
# FAQs / Troubleshooting
## Usage with Expo
If you use Expo and would like to use this package, you'll need to eject. If you do not want to eject, but wish to make use of features
such as Realtime Database (without offline support) & Authentication, you can still use the Firebase Web SDK in your project.
For features such a Crash Reporting, Push Notifications (via Firebase not Expo), Performance Monitoring, AdMob, Analytics, Storage & Remote Config, you will have to eject your Expo project as these require the native SDKs, as the Web SDK does not support these.
You can see an indepth conversation [here](https://expo.canny.io/feature-requests/p/full-native-firebase-integration).
## Comparison to Firestack
Firestack was a great start to integrating Firebase and React Native, however has underlying issues which needed to be fixed.
A V3 fork of Firestack was created to help address issues such as lack of standardisation with the Firebase Web SDK,
and missing core features (crash reporting, transactions etc). The volume of pull requests with fixes/features soon became
too large to manage on the existing repository, whilst trying to maintain backwards compatibility.
RNFirebase was re-written from the ground up, addressing these issues with core focus being around matching the Web SDK as
closely as possible and fixing the major bugs/issues along the way.
## [Android] Google Play Services related issues
The firebase SDK requires a certain version of Google Play Services installed on Android in order to function properly.
If the version of Google Play Services installed on your device is incorrect or non existent, React Native Firebase will throw a red box error, and your app will possibly crash as well. The red box error will have a numerical code associated with it. These codes can be found here:
https://developers.google.com/android/reference/com/google/android/gms/common/ConnectionResult#SERVICE_VERSION_UPDATE_REQUIRED
Here is a quick guide to some of the most common errors encountered:
code 2 - Google Play Services is required to run this application but no valid installation was found:
The emulator/device you're using does not have the Play Services SDK installed.
- Emulator: Open SDK manager, under 'SDK Tools' ensure "Google Play services, rev X" is installed. Once installed,
create a new emulator image. When selecting your system image, ensure the target comes "with Google APIs".
- Device: Play Services needs to be downloaded from the Google Play Store.
code 9 - The version of the Google Play services installed on this device is not authentic:
This error applies to modified or 'shimmed' versions of Google Play Services which you might be using in a third
party emulator such as GenyMotion.
Using this kind of workaround with Google Play Services can be problematic, so we
recommend using the native Android Studio emulators to reduce the chance of these complications.
## [Android] Turning off Google Play Services availability errors
G.P.S errors can be turned off using a config option like so:
```javascript
const firebase = RNFirebase.initializeApp({
errorOnMissingPlayServices: false,
});
```
This will stop your app from immediately red-boxing or crashing, but won't solve the underlying issue of G.P.S not being available or of the correct version. This will mean certain functionalities won't work properly and your app may even crash.
## [Android] Checking for Google Play Services availability with React Native Firebase
React Native Firebase actually has a useful helper object for checking G.P.S availability:
```javascript
const availability = firebase.googleApiAvailability;
```
The availability object would then have the following properties that you can run checks against:
```javascript
isAvailable: boolean
```
and if not available (isAvailable === false):
```javascript
isUserResolvableError: boolean
```
This variable indicates whether or not the end user can fix the issue, for example by downloading the required version of Google Play Services. In a case such as a GenyMotion emulator, this would return false for missing G.P.S, as the end user can't add the package directly.
```javascript
error: string
```
This error will match the messages and error codes mentioned above, and can be found here:
https://developers.google.com/android/reference/com/google/android/gms/common/ConnectionResult#SERVICE_VERSION_UPDATE_REQUIRED
## [Android] Duplicate Dex Files error (build time error)
A common build time error when using libraries that require google play services is of the form:
'Failed on android with com.android.dex.DexException: Multiple dex files... '
This error (https://github.com/invertase/react-native-firebase/issues/48) occurs because different versions of google play services or google play services modules are being required by different libraries.
The process to fix this is fairly manual and depends on your specific combination of external libraries. Essentially what's required is to check the app level build.gradle file of each external library and establish which ones have a Google Play Services dependency.
You then need to find the lowest common version of each G.P.S module dependency, require that in the app level build.gradle file of your own project, and exclude it from being required by the modules themselves. This will force the use of a consistent version of the G.P.S module.
It's not a good idea to modify the version within the library's build.gradle, as this will be overwritten when you update the library, which will lead to the build breaking again.
A good break down of this process can be found here:
https://medium.com/@suchydan/how-to-solve-google-play-services-version-collision-in-gradle-dependencies-ef086ae5c75f

21
docs/v2/initial-setup.md Normal file
View File

@@ -0,0 +1,21 @@
# Install the library
`npm install --save react-native-firebase`
# Initial 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](https://i.imgur.com/KbbamwD.png)
Each platform uses a different setup method after creating the project.
## iOS
For iOS, follow the instructions [here](/installation-ios).
## Android
For Android, follow the instructions [here](/installation-android).

View File

@@ -0,0 +1,184 @@
# Android Installation
## 1) Setup google-services.json
Download the `google-services.json` file provided by Firebase in the _Add Firebase to Android_ platform menu in your Firebase configuration console. This file should be downloaded to `YOUR_PROJECT/android/app/google-services.json`.
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'
```
## 2) Link RNFirebase
RNFirebase is split into separate modules to allow you to only include the Firebase functionality that you need in your application.
First add the project path to `android/settings.gradle`:
```
include ':react-native-firebase'
project(':react-native-firebase').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-firebase/android')
```
Now you need to include RNFirebase and the required Firebase dependencies in our `android/app/build.gradle` so that they are compiled as part of React Native. In the `dependencies` listing, add the appropriate `compile` lines:
```
dependencies {
// RNFirebase required dependencies
compile(project(':react-native-firebase')) {
transitive = false
}
compile "com.google.firebase:firebase-core:11.0.4"
// If you are receiving Google Play API availability issues, add the following dependency
compile "com.google.android.gms:play-services-base:11.0.4"
// RNFirebase optional dependencies
compile "com.google.firebase:firebase-ads:11.0.4"
compile "com.google.firebase:firebase-analytics:11.0.4"
compile "com.google.firebase:firebase-auth:11.0.4"
compile "com.google.firebase:firebase-config:11.0.4"
compile "com.google.firebase:firebase-crash:11.0.4"
compile "com.google.firebase:firebase-database:11.0.4"
compile "com.google.firebase:firebase-messaging:11.0.4"
compile "com.google.firebase:firebase-perf:11.0.4"
compile "com.google.firebase:firebase-storage:11.0.4"
}
```
To install `react-native-firebase` in your project, you'll need to import the packages you need from `io.invertase.firebase` in your project's `android/app/src/main/java/com/[app name]/MainApplication.java` and list them as packages for ReactNative in the `getPackages()` function:
```java
package com.youcompany.application;
// ...
// Required package
import io.invertase.firebase.RNFirebasePackage; // <-- Add this line
// Optional packages - add as appropriate
import io.invertase.firebase.admob.RNFirebaseAdMobPackage; //Firebase AdMob
import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage; // Firebase Analytics
import io.invertase.firebase.auth.RNFirebaseAuthPackage; // Firebase Auth
import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage; // Firebase Remote Config
import io.invertase.firebase.crash.RNFirebaseCrashPackage; // Firebase Crash Reporting
import io.invertase.firebase.database.RNFirebaseDatabasePackage; // Firebase Realtime Database
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; // Firebase Cloud Messaging
import io.invertase.firebase.perf.RNFirebasePerformancePackage; // Firebase Performance
import io.invertase.firebase.storage.RNFirebaseStoragePackage; // Firebase Storage
// ...
public class MainApplication extends Application implements ReactApplication {
// ...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNFirebasePackage(), // <-- Add this line
// Add these packages as appropriate
new RNFirebaseAdMobPackage(),
new RNFirebaseAnalyticsPackage(),
new RNFirebaseAuthPackage(),
new RNFirebaseRemoteConfigPackage(),
new RNFirebaseCrashPackage(),
new RNFirebaseDatabasePackage(),
new RNFirebaseMessagingPackage(),
new RNFirebasePerformancePackage(),
new RNFirebaseStoragePackage()
);
}
};
// ...
}
```
## 3) Cloud Messaging (optional)
If you plan on using [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/), add the following to `android/app/src/main/AndroidManifest.xml`.
Add permissions:
```xml
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE" />
```
Set app [launch mode](https://inthecheesefactory.com/blog/understand-android-activity-launchmode/en) inside activity props:
```xml
<activity
...
android:launchMode="singleTop"
>
```
Add messaging service:
```xml
<application ...>
<service
android:name="io.invertase.firebase.messaging.MessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="io.invertase.firebase.messaging.InstanceIdService" android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
```
If you would like to schedule local notifications then you also need to add the following:
```xml
<receiver android:name="io.invertase.firebase.messaging.RNFirebaseLocalMessagingPublisher"/>
<receiver android:enabled="true" android:exported="true" android:name="io.invertase.firebase.messaging.RNFirebaseSystemBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
```
## 4) Performance Monitoring (optional)
If you'd like to take advantage of Firebase's [Performance Monitoring](https://firebase.google.com/docs/perf-mon/), the following additions
to your project setup are required:
In your projects `android/build.gradle` file, add the plugin to your dependencies:
```
dependencies {
...
classpath 'com.google.firebase:firebase-plugins:1.1.0'
}
```
At the top of your `android/app/build.gradle` file, below other plugins, apply the `firebase-perf` plugin:
```
apply plugin: "com.android.application"
apply plugin: "com.google.firebase.firebase-perf"
```
In the same file, add the `firebase-perf` module to your dependencies:
```
dependencies {
...
compile "com.google.firebase:firebase-perf:11.0.0"
}
```

164
docs/v2/installation-ios.md Normal file
View File

@@ -0,0 +1,164 @@
# iOS Installation
Please note that there is a known issue when using Cocoapods with the `use_frameworks!` enabled. This is explained [here](https://github.com/invertase/react-native-firebase/issues/252#issuecomment-316340974). Unfortunately we don't currently have a workaround, but are engaging with Firebase directly to try and resolve the problem.
## 1) Setup GoogleService-Info.plist
Setup the `GoogleService-Info.plist` file by following the instructions and adding it to the root of your project at `ios/[YOUR APP NAME]/GoogleService-Info.plist` [here](https://firebase.google.com/docs/ios/setup#add_firebase_to_your_app).
### 1.1) Initialisation
Make sure you've added the following to the top of your `ios/[YOUR APP NAME]]/AppDelegate.m` file:
`#import <Firebase.h>`
and this to the `didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` method before the `return` statement:
`[FIRApp configure];`
## 2) Setup RNFirebase
Unfortunately, due to the fact that Firebase is much easier to setup using Cocoapods, *we do not recommend* `react-native link` as it is not customisable enough for our needs and we have had numerous problems reported.
### 2.0) If you don't already have Cocoapods set up
Follow the instructions to install Cocoapods and create your Podfile [here](https://firebase.google.com/docs/ios/setup#add_the_sdk).
**NOTE: The Podfile needs to be initialised in the `ios` directory of your project. Make sure to update cocoapods libs first by running `pod update`**
#### Troubleshooting
1) When running `pod install` you may encounter an error saying that a `tvOSTests` target is declared twice. This appears to be a bug with `pod init` and the way that react native is set up.
**Resolution:**
- Open your Podfile
- Remove the duplicate `tvOSTests` target nested within the main project target
- Re-run `pod install`.
2) When running `pod install` you may encounter a number of warnings relating to `target overrides 'OTHER_LDFLAGS'`.
**Resolution:**
- Open Xcode
- Select your project
- For each target:
-- Select the target
-- Click Build settings
-- Search for `other linker flags`
-- Add `$(inherited)` as the top line if it doesn't already exist
- Re-run `pod install`
3) When running `pod install` you may encounter a warning that a default iOS platform has been assigned. If you wish to specify a different minimum version:
**Resolution**
- Open your Podfile
- Uncomment the `# platform :ios, '9.0'` line by removing the `#` character
- Change the version as required
### 2.1) Add the required pods
Simply add the following to your `Podfile` either at the top level, or within the main project target:
```ruby
# Required by RNFirebase
pod 'Firebase/Core'
pod 'RNFirebase', :path => '../node_modules/react-native-firebase'
# [OPTIONAL PODS] - comment out pods for firebase products you won't be using.
pod 'Firebase/AdMob'
pod 'Firebase/Analytics'
pod 'Firebase/Auth'
pod 'Firebase/Crash'
pod 'Firebase/Database'
pod 'Firebase/DynamicLinks'
pod 'Firebase/Messaging'
pod 'Firebase/RemoteConfig'
pod 'Firebase/Storage'
```
If you do not already have React and Yoga installed as pods, then add Yoga and React to your `Podfile` as follows:
```ruby
pod "Yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'BatchedBridge', # Required For React Native 0.45.0+
'Core',
# Add any other subspecs you want to use in your project
]
```
Run `pod install`.
**NOTE: You need to use the `ios/[YOUR APP NAME].xcworkspace` instead of the `ios/[YOUR APP NAME].xcproj` file from now on.**
#### Troubleshooting
1) You receive an error `No podspec found for 'RNFirebase'`
**Resolution**
- Run `npm install --save react-native-firebase` from the root of your project
## 3) Cloud Messaging (optional)
If you plan on using [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging/) then, you need to:
**NOTE: FCM does not work on the iOS simulator, you must test is using a real device. This is a restriction enforced by Apple for some unknown reason.**
### 3.1) Set up certificates
Follow the instructions at https://firebase.google.com/docs/cloud-messaging/ios/certs
### 3.2) Enable capabilities
In Xcode, enable the following capabilities:
1) Push Notifications
2) Background modes > Remote notifications
### 3.3) Update `AppDelegate.h`
Add the following import:
`@import UserNotifications;`
Change the interface descriptor to:
`@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>`
### 3.4) Update `AppDelegate.m`
Add the following import:
`#import "RNFirebaseMessaging.h"`
Add the following to the `didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` method after `[FIRApp Configure]`:
`[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];`
Add the following methods:
```objectivec
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[RNFirebaseMessaging didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo {
[RNFirebaseMessaging didReceiveRemoteNotification:userInfo];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo
fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[RNFirebaseMessaging didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
[RNFirebaseMessaging willPresentNotification:notification withCompletionHandler:completionHandler];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler {
[RNFirebaseMessaging didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
```
### 3.5) Debugging
If you're having problems with messages not being received, check out the following blog post for help:
https://firebase.googleblog.com/2017/01/debugging-firebase-cloud-messaging-on.html

170
docs/v2/migration-guide.md Normal file
View File

@@ -0,0 +1,170 @@
# Migration
## From v1 to v2
The below is a quick summary of steps to take when migrating from v1 to v2 of RNFirebase. Please see the [v2 change log](https://github.com/invertase/react-native-firebase/releases/tag/v2.0.0) for detailed changes.
##### 1) Install the latest version of RNFirebase:
> `npm i react-native-firebase@latest --save`
##### 2) Upgrade react-native version (only if you're currently lower than v0.40):
> For example: `npm i react-native@0.44.0 react@16.0.0-alpha.6 --save`
##### 3) Update your JS code to reflect deprecations/breaking changes:
- [deprecated] providerId should now be used instead of provider whilst obtaining auth credentials. The latter will be removed in future releases.
- [deprecated] Deprecated User.getToken in favour of User.getIdToken.
- [breaking] User.reauthenticate has been removed in favour of User.reauthenticateWithCredential.
- [breaking] User.link has been removed in favour of User.linkWithCredential.
- [breaking] Removed unnecessary didReceiveNotificationResponse and willPresentNotification methods for iOS messaging. Added additional didReceiveRemoteNotification method.
- [breaking] firebase.messaging().onTokenRefresh and firebase.messaging().onMessage return a function to unsubscribe as per the Web SDK spec: https://firebase.google.com/docs/reference/js/firebase.messaging.Messaging#onMessage. Previously they returned an object with a .remove() method.
##### 4) Android - Update `android/build.gradle`:
The latest google-services version needs to be used:
```groovy
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
```
##### 5) Android - Update `app/build.gradle`:
All firebase modules are now optional so you only need to import the Firebase functionality that you require in your application.
You need to make a couple of changes to your `app/build.gradle` file. Update the react-native-firebase compile statement to read:
```groovy
compile(project(':react-native-firebase')) {
transitive = false
}
compile "com.google.firebase:firebase-core:11.0.0"
```
Add each of the firebase modules you need from the following list:
```groovy
compile "com.google.firebase:firebase-ads:11.0.0"
compile "com.google.firebase:firebase-analytics:11.0.0"
compile "com.google.firebase:firebase-auth:11.0.0"
compile "com.google.firebase:firebase-config:11.0.0"
compile "com.google.firebase:firebase-crash:11.0.0"
compile "com.google.firebase:firebase-database:11.0.0"
compile "com.google.firebase:firebase-messaging:11.0.0"
compile "com.google.firebase:firebase-perf:11.0.0"
compile "com.google.firebase:firebase-storage:11.0.0"
```
##### 6) Android - Update `MainApplication.java`:
Update `MainApplication.java` and import the modules you require / currently use:
```java
import io.invertase.firebase.admob.RNFirebaseAdMobPackage; //Firebase AdMob
import io.invertase.firebase.analytics.RNFirebaseAnalyticsPackage; // Firebase Analytics
import io.invertase.firebase.auth.RNFirebaseAuthPackage; // Firebase Auth
import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage; // Firebase Remote Config
import io.invertase.firebase.crash.RNFirebaseCrashPackage; // Firebase Crash Reporting
import io.invertase.firebase.database.RNFirebaseDatabasePackage; // Firebase Realtime Database
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage; // Firebase Cloud Messaging
import io.invertase.firebase.perf.RNFirebasePerformancePackage; // Firebase Performance Monitoring
import io.invertase.firebase.storage.RNFirebaseStoragePackage; // Firebase Storage
```
Add the packages to the `getPackages()` method as required:
```java
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNFirebasePackage(), // <-- Keep this line - it's the only one that's required
// add these optional packages as appropriate
new RNFirebaseAdMobPackage(),
new RNFirebaseAnalyticsPackage(),
new RNFirebaseAuthPackage(),
new RNFirebaseRemoteConfigPackage(),
new RNFirebaseCrashPackage(),
new RNFirebaseDatabasePackage(),
new RNFirebaseMessagingPackage(),
new RNFirebasePerformancePackage(),
new RNFirebaseStoragePackage()
);
}
```
##### 7) iOS - Update podfile:
First, delete your `Podfile.lock` file, and after making any changes from the below re-run `pod install` in your ios directory.
As all firebase modules are now optional you only need to import the Firebase functionality that you require in your application. Simply update your Podfile to only include the Firebase modules for functionality that you require in your app.
For example if you only use Auth and Storage in your app then your podfile would look like the below:
```ruby
install! 'cocoapods', :deterministic_uuids => false
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
target 'ReactNativeFirebaseDemo' do
platform :ios, '8.0'
# Uncomment this line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
react_native_path = "../node_modules/react-native"
pod "Yoga", :path => "#{react_native_path}/ReactCommon/yoga"
pod 'React', :path => '#{react_native_path}', :subspecs => [
'BatchedBridge', # Required For React Native 0.45.0+
'Core',
# Add any other subspecs you want to use in your project
# ...
]
# Core is always required
pod 'Firebase/Core'
# Optional modules
pod 'Firebase/Auth'
pod 'Firebase/Storage'
pod 'RNFirebase', :path => '../node_modules/react-native-firebase'
end
```

382
docs/v2/modules/admob.md Normal file
View File

@@ -0,0 +1,382 @@
# AdMob
The admob allows you to display adverts in your app, using your account from [AdMob by Google](https://www.google.co.uk/admob/). RNFirebase allows you to display Banners, Interstitials, NativeExpress Ads & Rewarded Videos.
## Initialize
Before using any AdMob feature, ensure you call the initialize method. This only needs to be done once per the apps lifecycle.
Initialize takes your AdMob App ID, where you can find on your AdMob dashboard.
> For testing purposes, you can use AdMobs test app ID "ca-app-pub-3940256099942544~3347511713".
```js
firebase.admob().initialize("ca-app-pub-3940256099942544~3347511713");
```
## Debugging
Once initialized, you can debug ((Android)[https://developers.google.com/mobile-ads-sdk/docs/dfp/android/debug]/(iOS)[https://developers.google.com/mobile-ads-sdk/docs/dfp/ios/debug])
your ads using the debug menu.
```js
firebase.admob().openDebugMenu();
```
## API
### Banner
AdMob Banners in RNFirebase are exported as a usable React component, allowing you to integrate it easily into your existing app very easily.
#### Props
| Prop | Type | Default | Description |
| ------------------- | ------------------ | --------------------------------------- | ----------------------------------------------------------------------------------- |
| size | string (See Sizes) | SMART_BANNER | Returns a sized banner (automatically sets View style) |
| unitId | string | | Your AdMob banner unit ID. |
| request | AdRequest | new AdRequest().addTestDevice().build() | An instance of AdRequest to load with the Banner |
| onAdLoaded | function | | Called when an ad is received. |
| onAdOpened | function | | Called when an ad opens an overlay that covers the screen. |
| onAdLeftApplication | function | | Called when an ad leaves the application (e.g., to go to the browser). |
| onAdClosed | function | | Called when the user is about to return to the application after clicking on an ad. |
| onAdFailedToLoad | function | | Called when an ad request failed. See Error Handling |
#### Example
```js
const Banner = firebase.admob.Banner;
const AdRequest = firebase.admob.AdRequest;
const request = new AdRequest();
request.addKeyword('foobar');
...
render() {
return (
<Banner
size={"LARGE_BANNER"}
request={request.build()}
onAdLoaded={() => {
console.log('Advert loaded and is now visible');
}}
/>
);
}
```
### Interstitial
An interstitial is a full screen advert which creates a new activity on top of React. As they need to be controlled,
allowing the developer to choose when to display them they're not available as a component. Instead they're controlled via
method calls.
A single interstitial instance can only be shown once. If you want to display another, create a new one.
To request an interstitial from AdMob, the `loadAd` method must be called with an instance of `AdRequest` (see below for full API):
#### Methods
| Method | Description |
| ------------------- | ---------------------------------------------------------------------------- |
| loadAd(AdRequest) | Loads an advert with request config |
| on(event, callback) | Listens to advert events. See Event Types for more information. |
| isLoaded() | Returns a boolean value as to whether the advert is loaded and ready to show.|
| show() | Show the advert on the device |
#### Example
```js
const advert = firebase.admob().interstitial('ca-app-pub-3940256099942544/1033173712');
const AdRequest = firebase.admob.AdRequest;
const request = new AdRequest();
request.addKeyword('foo').addKeyword('bar');
// Load the advert with our AdRequest
advert.loadAd(request.build());
advert.on('onAdLoaded', () => {
console.log('Advert ready to show.');
});
// Simulate the interstitial being shown "sometime" later during the apps lifecycle
setTimeout(() => {
if (advert.isLoaded()) {
advert.show();
} else {
// Unable to show interstitial - not loaded yet.
}
}, 1000);
```
### Native Express
An AdMob Native Express advert is much like a standard Banner, except it can be integrated seamlessly into your app using user predefined
styling (background color, positions, font size etc). Native Express adverts are exported as a usable React component.
#### Props
| Prop | Type | Default | Description |
| ------------------- | ------------------ | --------------------------------------- | ----------------------------------------------------------------------------------- |
| size | string (See Sizes) | SMART_BANNER | TODO |
| unitId | string | | Your AdMob banner unit ID. |
| request | AdRequest | new AdRequest().addTestDevice().build() | An instance of AdRequest to load with the Banner |
| video | AdRequest | new VideoOptions().build() | An instance of AdRequest to load with the Banner |
| onAdLoaded | function | | Called when an ad is received. |
| onAdOpened | function | | Called when an ad opens an overlay that covers the screen. |
| onAdLeftApplication | function | | Called when an ad leaves the application (e.g., to go to the browser). |
| onAdClosed | function | | Called when the user is about to return to the application after clicking on an ad. |
| onAdFailedToLoad | function | | Called when an ad request failed. See Event PropTypes for more information. |
| onVideoEnd | function | | Called if the advert video has ended (only called if the advert has a video). |
#### Usage
```js
const Banner = firebase.admob.Banner;
const NativeExpress = firebase.admob.NativeExpress;
const AdRequest = firebase.admob.AdRequest;
const request = new AdRequest();
request.addKeyword('foobar');
...
render() {
return (
<NativeExpress
size={"300x400"}
request={request.build()}
onAdLoaded={() => {
console.log('Advert loaded and is now visible');
}}
/>
);
}
```
### Rewarded Video
A rewarded video allows you to display a video to a user, whereby they're able to watch it to gain "rewards", or skip it
and receive nothing. For example, when a user completes a level on your gaming app, show them a video which will give them in-game
credit.
A single rewarded video instance can only be shown once. If you want to display another, create a new one.
?> It's recommended you begin loading the video as soon as possible.
To request an Rewarded Video from AdMob, the `loadAd` method must be called with an instance of `AdRequest` (see below for full API):
#### Methods
| Method | Description |
| ------------------- | ---------------------------------------------------------------------------- |
| loadAd(AdRequest) | Loads an advert with request config |
| on(event, callback) | Listens to advert events. See Event Types |
| isLoaded() | Returns a boolean value as to whether the advert is loaded and ready to show |
| show() | Show the advert on the device |
#### Example
```js
const advert = firebase.admob().rewarded('ca-app-pub-3940256099942544/1033173712');
const AdRequest = firebase.admob.AdRequest;
const request = new AdRequest();
request.addKeyword('foo').addKeyword('bar');
// Load the advert with our AdRequest
advert.loadAd(request.build());
advert.on('onAdLoaded', () => {
console.log('Advert ready to show.');
});
advert.on('onRewarded', (event) => {
console.log('The user watched the entire video and will now be rewarded!', event);
});
...
onLevelComplete()
.then(() => {
if (advert.isLoaded()) {
advert.show();
} else {
// skip...
}
});
```
### AdRequest
The AdRequest class is used to create an object to be passed to each advert request. The request is handled on AdMob,
and returns adverts tailored to the request options provided.
!> If no AdRequest is sent, the default request calls `addTestDevice`. Therefore, ensure a custom AdRequest object is passed through
in production.
##### build()
Builds the current request for AdMob to handle.
##### addTestDevice(device?: string)
Sets a device ID as a test device. If no device string is passed, a default emulator id is passed.
##### addKeyword(keyword: `string`)
Add a new keyword to relate the advert to.
##### setBirthday(date: `Date`)
Sets the user's birthday for targeting purposes.
##### setGender(gender: `male | female | unknown`)
Sets the user's gender for targeting purposes.
##### setLocation()
Sets the user's location for targeting purposes.
##### setRequestAgent(requestAgent: `string`)
Sets the request agent string to identify the ad request's origin. Third party libraries that reference the Mobile Ads SDK should call this method to denote the platform from which the ad request originated. For example, if a third party ad network called "CoolAds network" mediates requests to the Mobile Ads SDK, it should call this method with "CoolAds"
##### setContentUrl(url: `string`)
Sets the content URL for targeting purposes.
##### [android] setIsDesignedForFamilies(forFamilies: `boolean`)
If you set this value to true, you indicate that your app requires that the ad request should return a Designed for Families-compliant ad.
If you set this value to false, you indicate that your app does not require that the ad request should return a Designed for Families-compliant ad.
##### tagForChildDirectedTreatment(forChildren: `boolean`)
### VideoOptions
The VideoOptions class is used to create an object to be passed through to each advert request. If the advert returns a video,
the options are used when displaying it on the application.
?> Currently `NativeExpress` only accepts VideoOptions. If no VideoOptions are sent, the default options call `setStartMuted(true)`.
##### build()
Builds the current options for AdMob to handle.
##### setStartMuted(muted: `boolean`)
If true, any returned video will not play sound when it starts. The end user can manually enable sound on the advert interface.
## Prop Types
##### size: `String`
Sets the size of an Advert. Can be one of the following or a custom size:
| Size | Description |
| ----------------- | ------------------------------------------------------------------------------------------------------ |
| BANNER | Mobile Marketing Association (MMA) banner ad size (320x50 density-independent pixels). |
| FULL_BANNER | Interactive Advertising Bureau (IAB) full banner ad size (468x60 density-independent pixels). |
| LARGE_BANNER | Large banner ad size (320x100 density-independent pixels). |
| LEADERBOARD | Interactive Advertising Bureau (IAB) leaderboard ad size (728x90 density-independent pixels). |
| MEDIUM_RECTANGLE | Interactive Advertising Bureau (IAB) medium rectangle ad size (300x250 density-independent pixels). |
| SMART_BANNER | A dynamically sized banner that is full-width and auto-height. |
To specify a custom size, pass a string with the width and height split by an "x" (follows the Regex pattern `([0-9]+)x([0-9]+)`), e.g 320x150
?> Requesting an advert with a size which does not exist on the AdMob servers will return `admob/error-code-internal-error`.
##### unitId: `String`
The unit ID for the banner. Defaults to the testing unitId provided by Google for the advert type.
##### request: `AdRequest`
A built AdRequest object returned from `AdRequest.build()`.
##### video: `VideoOptions`
A built VideoOptions object returned from `VideoOptions.build()`.
### Events
Every advert returns common event types. On component based adverts (e.g. Banner) they're available as props and on instance based
adverts (e.g. Interstitial) they're available via the `on` method.
##### onAdLoaded(config: `Object`)
!> The config is not provided for Interstitial or Rewarded Video adverts.
On successful response from the AdMob servers. This is also called when a new banner is automatically loaded from the AdMob servers if the current one expires.
Returns an object of config data related to the loaded advert:
```js
{
hasVideoContent: boolean,
width: number,
height: number,
}
```
##### onAdOpened()
Called when the user presses the advert and it successfully opens.
##### onAdLeftApplication()
Called if the opened advert causes the user to leave the application, for example opening a URL in the browser.
##### onAdClosed()
Called when the user returns back to the application after closing an advert.
##### onAdFailedToLoad(error: `Error`)
Called when an advert fails to load. Returns a JavaScript Error with one of the following error codes.
| code | message |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| admob/error-code-internal-error | Something happened internally; for instance, an invalid response was received from the ad server. |
| admob/error-code-invalid-request | The ad request was invalid; for instance, the ad unit ID was incorrect. |
| admob/error-code-network-error | The ad request was unsuccessful due to network connectivity. |
| admob/error-code-no-fill | The ad request was successful, but no ad was returned due to lack of ad inventory. |
| admob/os-version-too-low | The current devices OS is below the minimum required version. |
##### [NativeExpress] onVideoEnd()
Called when video playback finishes playing.
##### [NativeExpress] onVideoMute(config: `Object`)
Called when the video changes mute state.
```js
{
isMuted: boolean,
}
```
##### [NativeExpress] onVideoPause()
Called when video playback is paused.
##### [NativeExpress] onVideoPlay()
Called when video playback is playing.
##### [NativeExpress] onVideoStart()
alled when video playback first begins.
##### [RewardedVideo] onRewarded(reward: `Object`)
Called when the user has been rewarded (usually for watching an entire video). Returns a reward object:
```js
{
type: string,
amount: number,
}
```
##### [RewardedVideo] onRewardedVideoStarted()
Called when a rewarded video has started to play.
## Statics
The following statics are available on the `firebase.admob` instance.
### Banner
Exports a React component to display an AdMob Banner.
### NativeExpress
Exports a React component to display an AdMob Native Express advert.
### AdRequest
Used to build a request object to pass into AdMob requests.
### VideoOptions
Used to build an options object for how videos should be handled with adverts containing a video.
### EventTypes
Returns all of the available advert event types.
### RewardedVideoEventTypes
Returns the extra event types for Rewarded Videos.
### NativeExpressEventTypes
Returns the extra event types for Native Express adverts.

View File

@@ -0,0 +1,90 @@
# Analytics
Integrating Firebase analytics is simple. 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 `logEvent` events:
```
'app_clear_data',
'app_uninstall',
'app_update',
'error',
'first_open',
'first_visit',
'first_open_time',
'first_visit_time',
'in_app_purchase',
'notification_dismiss',
'notification_foreground',
'notification_open',
'notification_receive',
'os_update',
'session_start',
'screen_view',
'user_engagement',
'ad_impression',
'ad_click',
'ad_query',
'ad_exposure',
'adunit_exposure',
'ad_activeiew',
```
#### `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 unique identification.
```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');
```

View File

@@ -0,0 +1,324 @@
# 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, see [examples](#examples)).
> 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](/modules/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',
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',
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().currentUser
.updateEmail('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().currentUser
.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().currentUser
.updateProfile({
displayName: 'Display Name'
})
.then()
.catch();
```
## Examples
### Facebook authentication with react-native-fbsdk and signInWithCredential
```javascript
import { AccessToken, LoginManager } from 'react-native-fbsdk';
// ... somewhere in your login screen component
LoginManager
.logInWithReadPermissions(['public_profile', 'email'])
.then((result) => {
if (result.isCancelled) {
return Promise.resolve('cancelled');
}
console.log(`Login success with permissions: ${result.grantedPermissions.toString()}`);
// get the access token
return AccessToken.getCurrentAccessToken();
})
.then(data => {
// create a new firebase credential with the token
const credential = firebase.auth.FacebookAuthProvider.credential(data.accessToken);
// login with credential
return firebase.auth().signInWithCredential(credential);
})
.then((currentUser) => {
if (currentUser === 'cancelled') {
console.log('Login cancelled');
} else {
// now signed in
console.warn(JSON.stringify(currentUser.toJSON()));
}
})
.catch((error) => {
console.log(`Login fail with error: ${error}`);
});
```

View File

@@ -0,0 +1,145 @@
# Cloud Messaging
Firebase Cloud Messaging ([FCM](https://firebase.google.com/docs/cloud-messaging/)) allows you to send push messages at no
cost to both Android & iOS platforms. Assuming the installation instructions have been followed, FCM is ready to go.
As the Firebase Web SDK has limited messaging functionality, the following methods within `react-native-firebase` have been
created to handle FCM in the React Native environment.
Badge notification is well known on the iOS platform, but also supported by different Android devices / launchers.
This library uses the [ShortcutBadger](https://github.com/leolin310148/ShortcutBadger) library to set the badge number
also on Android. A list of supported launcher can be found there.
!> [iOS] Please note: In order for iOS devices to receive Cloud Messages, ensure you [request permissions](http://invertase.io/react-native-firebase/#/modules/cloud-messaging?id=ios-requestpermissions).
## API
### subscribeToTopic(topic: string)
Subscribes the device to a topic.
```javascript
firebase.messaging().subscribeToTopic('foobar');
```
### unsubscribeFromTopic(topic: string)
Unsubscribes the device from a topic.
```javascript
firebase.messaging().unsubscribeFromTopic('foobar');
```
### getInitialNotification(): `Promise<Object>`
When the application has been opened from a notification `getInitialNotification` is called and the notification payload
is returned. Use `onMessage` for notifications when the app is running.
```javascript
firebase.messaging().getInitialNotification()
.then((notification) => {
console.log('Notification which opened the app: ', notification);
});
```
### getToken(): `Promise<string>`
Returns the devices FCM token. This token can be used in the Firebase console to send messages to directly.
```javascript
firebase.messaging().getToken()
.then((token) => {
console.log('Device FCM Token: ', token);
});
```
### onTokenRefresh(listener: `Function<string>`)
On the event a devices FCM token is refreshed by Google, the new token is returned in a callback listener.
```javascript
firebase.messaging().onTokenRefresh((token) => {
console.log('Refreshed FCM token: ', token);
});
```
### onMessage(listener: `Function<Object>`)
On a new message, the payload object is passed to the listener callback. This method is only triggered when the app is
running. Use `getInitialNotification` for notifications which cause the app to open.
```javascript
firebase.messaging().onMessage((message) => {
// TODO
});
```
### createLocalNotification(notification: Object)
Create a local notification from the device itself.
// TODO
### scheduleLocalNotification(notification: Object)
Schedule a local notification to be shown on the device.
### getScheduledLocalNotifications(): `Promise<Array>`
Returns an array of all currently scheduled notifications.
```javascript
firebase.messaging().getScheduledLocalNotifications()
.then((notifications) => {
console.log('Current scheduled notifications: ', notifications);
});
```
### cancelLocalNotification(id: string)
Cancels a location notification by ID, or all notifications by `*`.
```javascript
// Cancel all local notifications
firebase.messaging().cancelLocalNotification('*');
// Cancel a single local notification
firebase.messaging().cancelLocalNotification('123');
```
### removeDeliveredNotification(id: string)
Removes all delivered notifications from device by ID, or all notifications by `*`.
```javascript
// Remove all notifications
firebase.messaging().removeDeliveredNotification('*');
// Removes a single local notification
firebase.messaging().removeDeliveredNotification('123');
```
### [iOS] requestPermissions()
Requests app notification permissions in an Alert dialog.
```javascript
firebase.messaging().requestPermissions();
```
### setBadgeNumber(value: number)
Sets the badge number on the iOS app icon.
```javascript
firebase.messaging().setBadgeNumber(2);
```
### getBadgeNumber(): `Promise<number>`
Returns the current badge number on the app icon.
```javascript
firebase.messaging().getBadgeNumber()
.then((badgeNumber) => {
console.log('Current badge number: ', badgeNumber);
});
```

149
docs/v2/modules/config.md Normal file
View File

@@ -0,0 +1,149 @@
# Remote Config
?> Remote Config is not available on the web SDK. Please read the [documentation](https://firebase.google.com/docs/remote-config) on when & why Remote Config benefits your app.
## API
### enableDeveloperMode()
Enable Remote Config developer mode to allow for frequent refreshes of the cache.
```js
firebase.config().enableDeveloperMode();
```
### setDefaults(defaults: `Object`)
Sets default values for the app to use when accessing values. Any data fetched and activated will override any default values.
Any values in the defaults but not on Firebase will be untouched.
```js
firebase.config().setDefaults({
hasExperimentalFeature: false,
});
```
### fetch(duration?: `number`): `Promise<String>`
Fetches the remote config data from Firebase, defined in the dashboard.
If duration is defined (seconds), data will be locally cached for this duration.
The default duration is 43200 seconds (12 hours). To force a cache refresh call the method with a duration of 0.
Thrown errors can be one of the following:
* config/failure - Config fetch failed.
* config/no_fetch_yet - Config has never been fetched.
* config/throttled - Config fetch was throttled.
```js
firebase.config()
.fetch()
.then(() => {
console.log('Successfully fetched data');
})
.catch((error) => {
console.error('Unable to fetch remote config data: ', error);
});
```
### activateFetched(): `Promise<Boolean>`
Moves fetched data in the apps active config. Always successfully resolves with a boolean value.
```js
firebase.config()
.activateFetched()
.then((success) => {
if (success) {
console.log('Successfully activated fetched config into active config');
} else {
console.log('No fetched config was found or fetched config is already active');
}
});
```
### getValue(key: `String`): `Promise<Object>`
Gets a config item by key. Returns an object containing source (default, remote or static) and val function.
```js
firebase.config()
.getValue('foobar')
.then((snapshot) => {
console.log('Got value from source: ', snapshot.source);
console.log('Value of foobar: ', snapshot.val());
})
.catch(console.error);
```
### getValues(keys: `Array<String>`): `Promise<Object>`
Gets multiple values by key. Returns an object of keys with the same object returned from `getValue`.
```js
firebase.config()
.getValues(['foobar', 'barbaz'])
.then((snapshot) => {
console.log('Value of foobar: ', snapshot.foobar.val());
console.log('Value of barbaz: ', snapshot.barbaz.val());
})
.catch(console.error);
```
### getKeysByPrefix(prefix?: `String`): `Promise <Array<String>>`
Returns all keys as an array by a prefix. If no prefix is defined all keys are returned.
```js
firebase.config()
.getKeysByPrefix()
.then((keys) => {
console.log('Current keys: ', keys);
});
```
### setDefaultsFromResource(filename: `String`)
Sets the default values from a resource:
* Android: Id for the XML resource, which should be in your application's res/xml folder.
* iOS: The plist file name, with no file name extension
```js
// Anrdoid
firebase.config().setDefaultsFromResource(1337);
// iOS
firebase.config().setDefaultsFromResource('configDefaults');
```
## Usage
```js
if (__DEV__) {
firebase.config().enableDeveloperMode();
}
// Set default values
firebase.config().setDefaults({
hasExperimentalFeature: false,
});
firebase.config().fetch()
.then(() => {
return firebase.config().activateFetched();
})
.then((activated) => {
if (!activated) console.log('Fetched data not activated');
return firebase.config().getValue('hasExperimentalFeature');
})
.then((snapshot) => {
const hasExperimentalFeature = snapshot.val();
if(hasExperimentalFeature) {
// enableSuperCoolFeature();
}
// continue booting app
})
.catch(console.error);
```

54
docs/v2/modules/crash.md Normal file
View File

@@ -0,0 +1,54 @@
# Crash Reporting
RNFirebase provides crash reporting for your app out of the box. Please note crashes do not appear in real-time on the console, they tend to take a number of hours to appear.
## Enabling/Disabling Crash Reporting
By default crash reporting is enabled. If you want to disable reporting, call `setCrashCollectionEnabled(enabled: Boolean)`:
```js
firebase.crash().setCrashCollectionEnabled(false);
```
To check if crash reporting is currently enabled, call `isCrashCollectionEnabled(): Promise<boolean>`:
```js
firebase.crash().isCrashCollectionEnabled()
.then((enabled) => {
if (enabled) {
console.log('Crash Reporting is currently enabled');
}
});
```
## Manual Crash Reporting
If you want to manually report a crash, such as a pre-caught exception this is possible by using the `report` method.
```javascript
try {
initSomeSDK();
} catch (e) {
firebase.crash().log('Some SDK failed to boot!');
firebase.crash().report(e);
}
```
### log
Logs a message that will appear in a subsequent crash report.
`firebase.crash().log(String message);`
### logcat
- **Android**: Logs a message that will appear in a subsequent crash report as well as in [logcat](https://developer.android.com/studio/command-line/logcat.html).
- **iOS**: Logs the message in the subsequest crash report only (same as `log`).
`firebase.crash().logcat(int level, String tag, String message);`
### report
Files a crash report, along with any previous logs to Firebase. An [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) object must be passed into the report method.
`firebase.crash().report(Error, int maxStackSize)`.

204
docs/v2/modules/database.md Normal file
View File

@@ -0,0 +1,204 @@
# 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
Firebase 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 behaves 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);
```
#### Security rules and offline persistence
Bear in mind that security rules live on the firebase server and **not in the client**. In other words, when offline, your app knows nothing about your database's security rules. This can lead to unexpected behaviour, which is explained in detail in the following blog post: https://firebase.googleblog.com/2016/11/what-happens-to-database-listeners-when-security-rules-reject-an-update.html
Some examples of behaviour you may not expect but may encounter are:
- Values that should not be readable, according to your security rules, are readable if they were created on the same device.
- Values are readable even when not authenticated, if they were created on the same device.
- Locations are writable even when they should not be, according to your security rules. This is more likely to cause unwanted behaviour when your app is offline, because when it is *online* the SDK will very quickly roll back the write once the server returns a permission error.

66
docs/v2/modules/perf.md Normal file
View File

@@ -0,0 +1,66 @@
# Performance Monitoring
!> Performance monitoring requires react-native-firebase version 1.2.0.
?> Android: If you plan on using this module in your own application, please ensure the optional setup instructions for
[Android](http://invertase.io/react-native-firebase/#/installation-android?id=_4-performance-monitoring-optional) have been followed.
Out of the box, [Firebase Performance Monitoring](https://firebase.google.com/docs/perf-mon/automatic) monitors a number of
[automatic traces](https://firebase.google.com/docs/perf-mon/automatic) such as app start/background/foreground response times.
You can easily trace your own events with RNFirebase:
## API
#### setPerformanceCollectionEnabled(enabled: `boolean`)
Globally enables or disables performance monitoring capture across the app.
```js
firebase.perf().setPerformanceCollectionEnabled(false); // Disable
```
#### newTrace(id: `string`): `Trace`
Returns a new instance of Trace (see API below). The id is the unique name of something you'd like to run performance
monitoring against.
```js
const trace = firebase.perf().newTrace("test_trace");
```
### Trace
!> Once a trace has been started and stopped, you cannot re-start it in the same app lifecycle.
#### start()
Initializes the trace to start tracing performance to relay back to Firebase.
```js
trace.start();
```
#### incrementCounter(event: string)
Notifies Firebase an event has occured. These events will be visible on Firebase once your trace has stopped.
```js
someCacheService.get('user:123')
.then((user) => {
if (user) {
trace.incrementCounter('user_cache_hit');
} else {
trace.incrementCounter('user_cache_missed');
}
});
```
#### stop()
Stops performance tracing. The completed trace stats are now sent to Firebase.
?> Results are not realtime. They can take a number of hours to appear in the Firebase console.
```js
trace.stop();
```

100
docs/v2/modules/storage.md Normal file
View File

@@ -0,0 +1,100 @@
# Storage
RNFirebase mimics the [Web Firebase SDK Storage](https://firebase.google.com/docs/storage/web/start), whilst
providing some iOS and Android specific functionality.
## Uploading files
### Simple
```javascript
firebase.storage()
.ref('/files/1234')
.putFile('/path/to/file/1234')
.then(uploadedFile => {
//success
})
.catch(err => {
//Error
});
```
### With metadata
```javascript
const metadata = {
contentType: 'image/jpeg'
}
firebase.storage()
.ref('/files/1234')
.putFile('/path/to/file/1234', metadata)
```
### 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()

View File

@@ -0,0 +1,35 @@
# Transactions
?> For help on how to use firebase transactions please see the [Firebase Transaction Documentation](https://firebase.google.com/docs/reference/js/firebase.database.Reference#transaction).
### Android Implementation
The [android implementation](https://github.com/invertase/react-native-firebase/blob/master/android/src/main/java/io/invertase/firebase/database/RNFirebaseTransactionHandler.java) makes use of [Condition](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html) and [ReentrantLock](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html) locks to handle transactions across the React Native Bridge.
### iOS Implementation
The [iOS implementation](https://github.com/invertase/react-native-firebase/blob/master/ios/RNFirebase/RNFirebaseDatabase.m#L279) makes use of GCD (Grand Central Dispatch) to handle transactions across the React Native Bridge without blocking the application thread. Check out [this](https://mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html) post for some 'light' reading about it.
!> Transactions that receive no response from react native's JS thread within 30 seconds are automatically aborted - this value is currently not configurable - PR welcome.
## Example
```javascript
const ref = firebase.database().ref('user/posts');
ref.transaction((posts) => {
return (posts || 0) + 1;
}, (error, committed, snapshot) => {
if (error) {
console.log('Something went wrong', error);
} else if (!committed) {
console.log('Aborted'); // Returning undefined will trigger this
} else {
console.log('User posts incremented by 1');
}
console.log('User posts is now: ', snapshot.val());
});
```

125
docs/v2/redux.md Normal file
View File

@@ -0,0 +1,125 @@
# Usage with Redux
Although RNFirebase usage requires a React Native environment, it isn't tightly coupled which allows for full flexibility
when it comes to integrating with other modules such a [`react-redux`](https://github.com/reactjs/react-redux). If you wish to use
a Redux library designed for Firebase, we suggest taking a look at [`react-redux-firebase`](http://docs.react-redux-firebase.com/history/v2.0.0/docs/recipes/react-native.html)
for implementation with this module.
## Standalone integration
Although the following example works for a basic redux setup, it may differ when integrating with other redux middleware.
Imagine a simple TODO app, with redux we're able to abstract the Firebase logic out of components which allows for greater
testability and maintainability.
?> We use [`redux-thunk`](https://github.com/gaearon/redux-thunk) to provide async actions.
### Action Creators
```js
// Actions
export const subscribe = () => {
return (dispatch) => {
firebase.database().ref('todos').on('value', (snapshot) => {
const todos = [];
snapshot.forEach((childSnapshot) => {
todos.push({
id: childSnapshot.key,
...(childSnapshot.val()),
})
})
dispatch({
type: 'TODO_UPDATE',
todos,
})
})
}
}
// Methods
export const addTodo = text => {
firebase.database().ref('todos').push({
text,
visible: true,
})
}
export const completeTodo = id => {
firebase.database().ref(`todos/${id}`).update({
visible: false,
})
}
```
Instead of creating multiple actions which the reducers handle, we instead subscribe to the database ref and on any changes,
send a single action for the reducers to handle with the data which is constantly updating.
### Reducers
Our reducer now becomes really simple, as we're able to simply update the reducers state with whatever data has been returned
from our Firebase subscription.
```js
const todos = (state = {}, action) => {
switch (action.type) {
case 'TODO_UPDATE':
return { ...action.todos };
}
return state;
}
export default todos;
```
### Component
We can now easily subscribe to the todos in redux state and get live updates when Firebase updates.
```js
import React from 'react';
import { FlatList } from 'react-native';
import { connect } from 'react-redux';
import { subscribe, addTodo, completeTodo } from '../actions/TodoActions.js';
...
class Todos extends React.Component {
componentDidMount() {
this.props.dispatch(
subscribe()
);
}
onComplete = (id) => {
this.props.dispatch(
completeTodo(id)
);
};
onAdd = (text) => {
this.props.dispatch(
addTodo(text)
);
};
render() {
return (
<FlatList
data={this.props.todos}
...
/>
);
}
}
function mapStateToProps(state) {
return {
todos: state.todos,
};
}
export default connect(mapStateToProps)(Todos);
```

38
docs/v2/usage.md Normal file
View File

@@ -0,0 +1,38 @@
# 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 = RNFirebase.initializeApp({
// config options
});
```
## Configuration Options
| 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. |
| errorOnMissingPlayServices | bool | true | (Android only) When set to true, will throw an error if Google Play Services isn't installed. |
| promptOnMissingPlayServices | bool | true | (Android only) When set to true, will prompt the user to install Google Play Services if it isn't installed. This takes precedence over `errorOnMissingPlayServices`.|
For instance:
```javascript
import RNFirebase from 'react-native-firebase';
const configurationOptions = {
debug: true
};
const firebase = RNFirebase.initializeApp(configurationOptions);
export default firebase;
```