Merge pull request #537 from invertase/docs-removal
[docs] Remove docs directory in favour of new site/docs
This commit is contained in:
commit
36d974a597
|
@ -1,65 +0,0 @@
|
||||||
!> This is our old documentation site, please use the new and improved documentation site: https://rnfirebase.io/
|
|
||||||
|
|
||||||
|
|
||||||
<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)
|
|
||||||
[![Donate](https://img.shields.io/badge/Donate-Patreon-green.svg?style=flat-square)](https://www.patreon.com/invertase)
|
|
||||||
[![Twitter Follow](https://img.shields.io/twitter/follow/rnfirebase.svg?style=social&label=Follow)](https://twitter.com/rnfirebase)
|
|
||||||
</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/functionality from the Web SDK are usable within React Native.
|
|
||||||
|
|
||||||
|
|
||||||
> '**?**' indicates partial support
|
|
||||||
|
|
||||||
| Firebase Features | v1.x.x | v2.x.x | v3.x.x | Web SDK |
|
|
||||||
| ---------------------- | :---: | :---: | :---: | :---: |
|
|
||||||
| **AdMob** | ❌ | ✅ | ✅ | ❌ |
|
|
||||||
| **Analytics** | ✅ | ✅ | ✅ | ❌ |
|
|
||||||
| **App Indexing** | ❌ | ❌ | ❌ | ❌ |
|
|
||||||
| **Authentication** | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| _-- Phone Auth_ | ❌ | ❌ | ✅ | ❌ |
|
|
||||||
| **Core** | ❌ |**?**| ✅ | ✅ |
|
|
||||||
| _-- Multiple Apps_ | ❌ | ❌ | ✅ | ✅ |
|
|
||||||
| **Cloud Messaging (FCM)** | ✅ | ✅ | ✅ |**?**|
|
|
||||||
| **Crash Reporting** | ✅ | ✅ | ✅ | ❌ |
|
|
||||||
| **Dynamic Links** | ❌ | ❌ | ✅ | ❌ |
|
|
||||||
| **Firestore** | ❌ | ❌ | ✅ | ❌ |
|
|
||||||
| **Invites** | ❌ | ❌ | ❌ | ❌ |
|
|
||||||
| **Performance Monitoring** | ✅ | ✅ | ✅ | ❌ |
|
|
||||||
| **Realtime Database** | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| _-- Offline Persistence_ | ✅ | ✅ | ✅ |**?**|
|
|
||||||
| _-- Transactions_ | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| **Remote Config** | ✅ | ✅ | ✅ | ❌ |
|
|
||||||
| **Storage** | ✅ | ✅ | ✅ |**?**|
|
|
||||||
|
|
||||||
---
|
|
||||||
### Supported versions - React Native / Firebase
|
|
||||||
|
|
||||||
> The table below shows the supported versions of React Native and the Firebase SDKs for different versions of `react-native-firebase`
|
|
||||||
|
|
||||||
| | 1.X.X | 2.0.X | 2.1.X / 2.2.X | 3.0.X |
|
|
||||||
|------------------------|-------------|-------------|-----------------|----------|
|
|
||||||
| React Native | 0.36 - 0.39 | 0.40 - 0.46 | 0.47 + | 0.48 + |
|
|
||||||
| Firebase Android SDK | 10.2.0 + | 11.0.0 + | 11.0.0 + | 11.4.2 + |
|
|
||||||
| Firebase iOS SDK | 3.15.0 + | 4.0.0 + | 4.0.0 + | 4.3.0 + |
|
|
|
@ -1,3 +0,0 @@
|
||||||
- <div class="version-select"><b>Version:</b> v3.x.x</div>
|
|
||||||
- [v2.x.x](/v2/)
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
- Getting started
|
|
||||||
- [Initial setup](/initial-setup)
|
|
||||||
- [Installation - iOS](/installation-ios)
|
|
||||||
- [Installation - Android](/installation-android)
|
|
||||||
- [Usage](/usage)
|
|
||||||
- [With Expo](/faq/expo)
|
|
||||||
- [With Redux](/redux)
|
|
||||||
- [Upgrade Guide](/migration-guide)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
- Core
|
|
||||||
- [Apps](/core/app)
|
|
||||||
- [Default App](/core/default-app)
|
|
||||||
- [Dynamically Initialize Apps](/core/initialize-apps)
|
|
||||||
- [Firebase](/core/firebase)
|
|
||||||
- [Configure RNFirebase](/core/config-rnfirebase)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
- Modules
|
|
||||||
- [Admob (Disable Adblock)](/modules/admob)
|
|
||||||
- [Analytics](/modules/analytics)
|
|
||||||
- [Authentication](/modules/authentication)
|
|
||||||
- [Cloud Messaging](/modules/cloud-messaging)
|
|
||||||
- [Crash Reporting](/modules/crash)
|
|
||||||
- [Database](/modules/database)
|
|
||||||
- [Dynamic Links](/modules/links)
|
|
||||||
- [Firestore (Beta)](/modules/firestore)
|
|
||||||
- [Remote Config](/modules/config)
|
|
||||||
- [Storage](/modules/storage)
|
|
||||||
- [Transactions](/modules/transactions)
|
|
||||||
- [Performance Monitoring](/modules/perf)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
- Contributing
|
|
||||||
- [Guidelines](/contributing/guidelines)
|
|
||||||
- [Testing](/contributing/testing)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
- Other
|
|
||||||
- [Feature Requests](https://react-native-firebase.canny.io/feature-requests)
|
|
||||||
- [FAQs / Troubleshooting](/faqs)
|
|
||||||
- Chat
|
|
||||||
- [Discord](https://discord.gg/t6bdqMs)
|
|
|
@ -1,5 +0,0 @@
|
||||||
# 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.
|
|
|
@ -1,330 +0,0 @@
|
||||||
# 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
|
|
||||||
```
|
|
|
@ -1,28 +0,0 @@
|
||||||
## Apps
|
|
||||||
|
|
||||||
?> For the **default** app see: [Default App](/core/default-app)
|
|
||||||
|
|
||||||
?> For initializing **additional apps** natively and also via js code over the RN bridge see: [Dynamically Initializing Apps](/core/initialize-apps)
|
|
||||||
|
|
||||||
### Reading App Options
|
|
||||||
|
|
||||||
!> `<app>.options.clientId` is not available on the **Android Firebase SDK** so will return null for Android, see the issue: [firebase/firebase-ios-sdk#140 (comment)](https://github.com/firebase/firebase-ios-sdk/issues/140#issuecomment-315953708)
|
|
||||||
|
|
||||||
Just like the Firebase web sdk you can view options used to initialize an app instance in the same way, for example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
const defaultApp = firebase.app();
|
|
||||||
|
|
||||||
// get the default app name/options that the app initialized with
|
|
||||||
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);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<!-- TODO -->
|
|
||||||
### Log Options
|
|
||||||
|
|
||||||
TODO - PR's welcome
|
|
||||||
|
|
||||||
### Debug Options
|
|
||||||
|
|
||||||
TODO - PR's welcome
|
|
|
@ -1,27 +0,0 @@
|
||||||
### Default Firebase App
|
|
||||||
|
|
||||||
After following the iOS & Android install guides and correctly setting up your google services plist/json files; the default app is automatically initialized and available for use in react-native-firebase.
|
|
||||||
|
|
||||||
There's no need to call `initializeApp(opt)` in your JS code for the default app, import RNFirebase and use the default app straight away:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
console.log(firebase.database().app.name); // '[DEFAULT]'
|
|
||||||
```
|
|
||||||
|
|
||||||
!> Calling `initializeApp()` for the default app will throw an 'app already initialized' error in a later release.
|
|
||||||
|
|
||||||
### Enable Database Persistence
|
|
||||||
|
|
||||||
Enabling database persistence (setPersistence) via JS for the default app is no longer supported. This breaking change was added in v3 to prevent several race condition issues around.
|
|
||||||
|
|
||||||
You can still however easily enable this natively for the default app instance:
|
|
||||||
|
|
||||||
#### Android
|
|
||||||
|
|
||||||
Add `FirebaseDatabase.getInstance().setPersistenceEnabled(true);` inside your `MainActivity.java` files `onCreate()` method.
|
|
||||||
|
|
||||||
#### iOS
|
|
||||||
|
|
||||||
Add `[FIRDatabase database].persistenceEnabled = YES;` after the `[FIRApp configure];` line inside your `AppDelegate.m` files `didFinishLaunchingWithOptions` method.
|
|
|
@ -1,10 +0,0 @@
|
||||||
# Firebase
|
|
||||||
|
|
||||||
TODO Reference Docs:
|
|
||||||
|
|
||||||
- apps(): Array<FirebaseApp>
|
|
||||||
- app(): FirebaseApp
|
|
||||||
- initializeApp(): FirebaseApp
|
|
||||||
- setLogLevel()
|
|
||||||
- SDK_VERSION: String
|
|
||||||
- googleApiAvailability: Object
|
|
|
@ -1,93 +0,0 @@
|
||||||
## Initializing Apps
|
|
||||||
|
|
||||||
!> The **default** firebase app instance can **not** be initialized via JS, please setup your google services plist/json files in your android studio / xcode projects. See [Default App](/core/default-app) for more information.
|
|
||||||
|
|
||||||
App initialization in RNFirebase is for the most part the same as the web sdk, with only a few minor differences.
|
|
||||||
|
|
||||||
### Supported Modules
|
|
||||||
|
|
||||||
Only 4 modules on the official firebase native SDK's support multiple apps, they are as follows:
|
|
||||||
|
|
||||||
- Authentication
|
|
||||||
- Database
|
|
||||||
- Firestore
|
|
||||||
- Storage
|
|
||||||
|
|
||||||
### Initialize via JavaScript
|
|
||||||
|
|
||||||
#### Cross Platform Example
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import { Platform } from 'react-native';
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
// pluck values from your `GoogleService-Info.plist` you created on the firebase console
|
|
||||||
const iosConfig = {
|
|
||||||
clientId: 'x',
|
|
||||||
appId: 'x',
|
|
||||||
apiKey: 'x',
|
|
||||||
databaseURL: 'x',
|
|
||||||
storageBucket: 'x',
|
|
||||||
messagingSenderId: 'x',
|
|
||||||
projectId: 'x',
|
|
||||||
|
|
||||||
// enable persistence by adding the below flag
|
|
||||||
persistence: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
// pluck values from your `google-services.json` file you created on the firebase console
|
|
||||||
const androidConfig = {
|
|
||||||
clientId: 'x',
|
|
||||||
appId: 'x',
|
|
||||||
apiKey: 'x',
|
|
||||||
databaseURL: 'x',
|
|
||||||
storageBucket: 'x',
|
|
||||||
messagingSenderId: 'x',
|
|
||||||
projectId: 'x',
|
|
||||||
|
|
||||||
// enable persistence by adding the below flag
|
|
||||||
persistence: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const kittensApp = firebase.initializeApp(
|
|
||||||
// use platform specific firebase config
|
|
||||||
Platform.OS === 'ios' ? iosConfig : androidConfig,
|
|
||||||
// name of this app
|
|
||||||
'kittens',
|
|
||||||
);
|
|
||||||
|
|
||||||
// dynamically created apps aren't available immediately due to the
|
|
||||||
// asynchronous nature of react native bridging, therefore you must
|
|
||||||
// wait for an `onReady` state before calling any modules/methods
|
|
||||||
// otherwise you will most likely run into `app not initialized` exceptions
|
|
||||||
kittensApp.onReady().then((app) => {
|
|
||||||
// --- ready ---
|
|
||||||
// use `app` arg, kittensApp var or `app('kittens')` to access modules
|
|
||||||
// and their methods. e.g:
|
|
||||||
firebase.app('kittens').auth().signInAnonymously().then((user) => {
|
|
||||||
console.log('kittensApp user ->', user.toJSON());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Initialize via Android/iOS native code
|
|
||||||
|
|
||||||
If you're familiar with native code you can create apps natively also (or if you are already initializing additional apps natively on app boot) - these apps automatically become available for use inside RNFirebase.
|
|
||||||
|
|
||||||
For example, if you created an app natively called `dogs` then the following would work:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
const dogsApp = firebase.app('dogs');
|
|
||||||
|
|
||||||
dogsApp.auth().signInAnonymously().then((user) => {
|
|
||||||
console.log('dogsApp user ->', user.toJSON());
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Deleting an app instance
|
|
||||||
|
|
||||||
Currently it's not possible to provide cross platform 'delete app' functionality as the Firebase Android SDK is missing the app delete method, this has been flagged with firebase ([firebase/firebase-ios-sdk#140 (comment)](https://github.com/firebase/firebase-ios-sdk/issues/140#issuecomment-315953708)).
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
### 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).
|
|
98
docs/faqs.md
98
docs/faqs.md
|
@ -1,98 +0,0 @@
|
||||||
# FAQs / Troubleshooting
|
|
||||||
|
|
||||||
## Usage with Expo
|
|
||||||
|
|
||||||
See [usage with expo](/faq/expo).
|
|
||||||
|
|
||||||
## 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
|
|
BIN
docs/icon.png
BIN
docs/icon.png
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB |
401
docs/index.html
401
docs/index.html
|
@ -1,401 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<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>
|
|
||||||
<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="./icon.png" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="rnfirebase-header">
|
|
||||||
<img src="https://static.invertase.io/assets/React-Native-Firebase.svg" alt="rnfirebase logo">
|
|
||||||
<span><a href="./">React Native Firebase</a></span>
|
|
||||||
</div>
|
|
||||||
<div id="app"></div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
window.$docsify = {
|
|
||||||
name: 'React Native Firebase - Documentation',
|
|
||||||
repo: 'https://github.com/invertase/react-native-firebase',
|
|
||||||
loadSidebar: true,
|
|
||||||
loadNavbar: true,
|
|
||||||
mergeNavbar: true,
|
|
||||||
search: 'auto',
|
|
||||||
themeColor: '#e88634',
|
|
||||||
subMaxLevel: 3,
|
|
||||||
maxLevel: 4,
|
|
||||||
ga: 'UA-98196653-1',
|
|
||||||
formatUpdated: '{DD}/{MM}/{YYYY} {HH}:{mm}',
|
|
||||||
plugins: [
|
|
||||||
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 me on Github](' + url + ')\n';
|
|
||||||
return html
|
|
||||||
+ '\n----\n'
|
|
||||||
+ '<b>Last updated</b>: {docsify-updated} '
|
|
||||||
+ editHtml
|
|
||||||
})
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<!--<script>-->
|
|
||||||
<!--if (typeof navigator.serviceWorker !== 'undefined') {-->
|
|
||||||
<!--navigator.serviceWorker.register('sw.js')-->
|
|
||||||
<!--}-->
|
|
||||||
<!--</script>-->
|
|
||||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
|
||||||
<style>
|
|
||||||
.markdown-section pre>code {
|
|
||||||
background: #383838;
|
|
||||||
}
|
|
||||||
.markdown-section pre {
|
|
||||||
background: #383838;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
display: block;
|
|
||||||
height: 1px;
|
|
||||||
border: 0;
|
|
||||||
border-top: 1px solid #e8e8e8;
|
|
||||||
margin: 1em 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
code[class*="lang-"],
|
|
||||||
pre[class*="lang-"] {
|
|
||||||
color: white !important;
|
|
||||||
background: none !important;
|
|
||||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace !important;
|
|
||||||
text-align: left !important;
|
|
||||||
text-shadow: 0 -.1em .2em black !important;
|
|
||||||
white-space: pre !important;
|
|
||||||
word-spacing: normal !important;
|
|
||||||
word-break: normal !important;
|
|
||||||
word-wrap: normal !important;
|
|
||||||
line-height: 1.5 !important;
|
|
||||||
|
|
||||||
-moz-tab-size: 4 !important;
|
|
||||||
-o-tab-size: 4 !important;
|
|
||||||
tab-size: 4 !important;
|
|
||||||
|
|
||||||
-webkit-hyphens: none !important;
|
|
||||||
-moz-hyphens: none !important;
|
|
||||||
-ms-hyphens: none !important;
|
|
||||||
hyphens: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre[class*="lang-"],
|
|
||||||
:not(pre) > code[class*="lang-"] {
|
|
||||||
background: hsl(0, 0%, 8%) !important; /* #141414 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Code blocks */
|
|
||||||
pre[class*="lang-"] {
|
|
||||||
border-radius: .5em !important;
|
|
||||||
border: .3em solid hsl(0, 0%, 33%) !important; /* #282A2B */
|
|
||||||
box-shadow: 1px 1px .5em black inset !important;
|
|
||||||
margin: .5em 0 !important;
|
|
||||||
overflow: auto !important;
|
|
||||||
padding: 1em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre[class*="lang-"]::-moz-selection {
|
|
||||||
/* Firefox */
|
|
||||||
background: hsl(200, 4%, 16%) !important; /* #282A2B */
|
|
||||||
}
|
|
||||||
|
|
||||||
pre[class*="lang-"]::selection {
|
|
||||||
/* Safari */
|
|
||||||
background: hsl(200, 4%, 16%) !important; /* #282A2B */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Text Selection colour */
|
|
||||||
pre[class*="lang-"]::-moz-selection, pre[class*="lang-"] ::-moz-selection,
|
|
||||||
code[class*="lang-"]::-moz-selection, code[class*="lang-"] ::-moz-selection {
|
|
||||||
text-shadow: none !important;
|
|
||||||
background: hsla(0, 0%, 93%, 0.15) !important; /* #EDEDED */
|
|
||||||
}
|
|
||||||
|
|
||||||
pre[class*="lang-"]::selection, pre[class*="lang-"] ::selection,
|
|
||||||
code[class*="lang-"]::selection, code[class*="lang-"] ::selection {
|
|
||||||
text-shadow: none !important;
|
|
||||||
background: hsla(0, 0%, 93%, 0.15) !important; /* #EDEDED */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inline code */
|
|
||||||
:not(pre) > code[class*="lang-"] {
|
|
||||||
border-radius: .3em !important;
|
|
||||||
border: .13em solid hsl(0, 0%, 33%) !important; /* #545454 */
|
|
||||||
box-shadow: 1px 1px .3em -.1em black inset !important;
|
|
||||||
padding: .15em .2em .05em !important;
|
|
||||||
white-space: normal !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.comment,
|
|
||||||
.token.prolog,
|
|
||||||
.token.doctype,
|
|
||||||
.token.cdata {
|
|
||||||
color: hsl(0, 0%, 58%) !important; /* #777777 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.punctuation {
|
|
||||||
opacity: .7 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.namespace {
|
|
||||||
opacity: .7 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.tag,
|
|
||||||
.token.boolean,
|
|
||||||
.token.number,
|
|
||||||
.token.deleted {
|
|
||||||
color: hsl(14, 58%, 55%) !important; /* #CF6A4C */
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.keyword,
|
|
||||||
.token.property,
|
|
||||||
.token.selector,
|
|
||||||
.token.constant,
|
|
||||||
.token.symbol,
|
|
||||||
.token.builtin {
|
|
||||||
color: hsl(27, 80%, 56%) !important; /* #F9EE98 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.attr-name,
|
|
||||||
.token.attr-value,
|
|
||||||
.token.string,
|
|
||||||
.token.char,
|
|
||||||
.token.operator,
|
|
||||||
.token.entity,
|
|
||||||
.token.url,
|
|
||||||
.lang-css .token.string,
|
|
||||||
.style .token.string,
|
|
||||||
.token.variable,
|
|
||||||
.token.inserted {
|
|
||||||
color: hsl(37, 100%, 80%) !important; /* #8F9D6A */
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.atrule {
|
|
||||||
color: hsl(218, 22%, 55%) !important; /* #7587A6 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.regex,
|
|
||||||
.token.important {
|
|
||||||
color: hsl(42, 75%, 65%) !important; /* #E9C062 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.important,
|
|
||||||
.token.bold {
|
|
||||||
font-weight: bold !important;
|
|
||||||
}
|
|
||||||
.token.italic {
|
|
||||||
font-style: italic !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.entity {
|
|
||||||
cursor: help !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre[data-line] {
|
|
||||||
padding: 1em 0 1em 3em !important;
|
|
||||||
position: relative !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Markup */
|
|
||||||
.language-markup .token.tag,
|
|
||||||
.language-markup .token.attr-name,
|
|
||||||
.language-markup .token.punctuation {
|
|
||||||
color: hsl(33, 33%, 52%) !important; /* #AC885B */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make the tokens sit above the line highlight so the colours don't look faded. */
|
|
||||||
.token {
|
|
||||||
position: relative !important;
|
|
||||||
z-index: 1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-highlight {
|
|
||||||
background: hsla(0, 0%, 33%, 0.25) !important; /* #545454 */
|
|
||||||
background: linear-gradient(to right, hsla(0, 0%, 33%, .1) 70%, hsla(0, 0%, 33%, 0)) !important; /* #545454 */
|
|
||||||
border-bottom: 1px dashed hsl(0, 0%, 33%) !important; /* #545454 */
|
|
||||||
border-top: 1px dashed hsl(0, 0%, 33%) !important; /* #545454 */
|
|
||||||
left: 0 !important;
|
|
||||||
line-height: inherit !important;
|
|
||||||
margin-top: 0.75em !important; /* Same as .prism’s padding-top */
|
|
||||||
padding: inherit 0 !important;
|
|
||||||
pointer-events: none !important;
|
|
||||||
position: absolute !important;
|
|
||||||
right: 0 !important;
|
|
||||||
white-space: pre !important;
|
|
||||||
z-index: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-highlight:before,
|
|
||||||
.line-highlight[data-end]:after {
|
|
||||||
background-color: hsl(215, 15%, 59%) !important; /* #8794A6 */
|
|
||||||
border-radius: 999px !important;
|
|
||||||
box-shadow: 0 1px white !important;
|
|
||||||
color: hsl(24, 20%, 95%) !important; /* #F5F2F0 */
|
|
||||||
content: attr(data-start) !important;
|
|
||||||
font: bold 65%/1.5 sans-serif !important;
|
|
||||||
left: .6em !important;
|
|
||||||
min-width: 1em !important;
|
|
||||||
padding: 0 .5em !important;
|
|
||||||
position: absolute !important;
|
|
||||||
text-align: center !important;
|
|
||||||
text-shadow: none !important;
|
|
||||||
top: .4em !important;
|
|
||||||
vertical-align: .3em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-highlight[data-end]:after {
|
|
||||||
bottom: .4em !important;
|
|
||||||
content: attr(data-end) !important;
|
|
||||||
top: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
padding-top: 45px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-link:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-name-link {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
padding-top: 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-corner {
|
|
||||||
height: 64px;
|
|
||||||
z-index: 9996;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-nav {
|
|
||||||
z-index: 9996;
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-corner > svg {
|
|
||||||
height: 64px;
|
|
||||||
width: 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rnfirebase-header {
|
|
||||||
width: 100%;
|
|
||||||
height: 64px;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
background: #383838;
|
|
||||||
z-index: 9995;
|
|
||||||
vertical-align: middle;
|
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
|
||||||
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
|
|
||||||
}
|
|
||||||
|
|
||||||
.warn {
|
|
||||||
box-shadow: 0 1px 2px rgba(0,0,0,0.16), 0 1px 2px rgba(0,0,0,0.23);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip {
|
|
||||||
box-shadow: 0 1px 2px rgba(200,0,0,0.16), 0 1px 2px rgba(0,0,0,0.23);
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
box-shadow: 0 1px 2px rgba(0,0,0,0.09), 0 1px 2px rgba(0,0,0,0.13);
|
|
||||||
}
|
|
||||||
|
|
||||||
li > a > code {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
.rnfirebase-header > img {
|
|
||||||
float: left;
|
|
||||||
width: 45px;
|
|
||||||
height: 45px;
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.version-select {
|
|
||||||
position: fixed;
|
|
||||||
right: 70px;
|
|
||||||
top: 13px;
|
|
||||||
background: rgb(255, 235, 213);
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid #e88634;
|
|
||||||
width: 110px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rnfirebase-header > span {
|
|
||||||
float: left;
|
|
||||||
height: 64px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 64px;
|
|
||||||
color: #e88634;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
a:-webkit-any-link:hover {
|
|
||||||
text-decoration:none !important;
|
|
||||||
margin-left: 3px;
|
|
||||||
}
|
|
||||||
.rnfirebase-header > span > a {
|
|
||||||
border:none;
|
|
||||||
outline:none;
|
|
||||||
text-decoration:none;
|
|
||||||
color:inherit;
|
|
||||||
-webkit-tap-highlight-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-toggle {
|
|
||||||
background-color: rgba(255, 255, 255, 0.92);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-nav li ul {
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-bottom-color: #ccc;
|
|
||||||
border-radius: 2px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: none;
|
|
||||||
max-height: calc(100vh - 61px);
|
|
||||||
overflow-y: scroll;
|
|
||||||
padding: 10px 0;
|
|
||||||
position: fixed;
|
|
||||||
right: 70px;
|
|
||||||
text-align: left;
|
|
||||||
top: 50px;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: 110px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
|
||||||
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
|
|
||||||
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
|
|
||||||
<script src="//unpkg.com/docsify/lib/plugins/ga.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-javascript.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-java.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-ruby.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-groovy.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-c.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-objectivec.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-swift.min.js"></script>
|
|
||||||
<script src="//unpkg.com/prismjs/components/prism-objectivec.min.js"></script>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
# 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.
|
|
||||||
|
|
||||||
## Starter Project
|
|
||||||
|
|
||||||
Fresh project and want to skip most of the setup? Check out our [starter app](
|
|
||||||
http://invertase.link/starter).
|
|
||||||
|
|
||||||
## iOS
|
|
||||||
|
|
||||||
For iOS, follow the instructions [here](/installation-ios).
|
|
||||||
|
|
||||||
## Android
|
|
||||||
|
|
||||||
For Android, follow the instructions [here](/installation-android).
|
|
|
@ -1,230 +0,0 @@
|
||||||
# Android Installation
|
|
||||||
|
|
||||||
## 1) Link RNFirebase
|
|
||||||
|
|
||||||
Run `react-native link react-native-firebase`
|
|
||||||
|
|
||||||
## 2) 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`
|
|
||||||
```groovy
|
|
||||||
buildscript {
|
|
||||||
// ...
|
|
||||||
dependencies {
|
|
||||||
// ...
|
|
||||||
classpath 'com.google.gms:google-services:3.1.1'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In your app build.gradle file, add the gradle plugin at the VERY BOTTOM of the file (below all dependencies)
|
|
||||||
`android/app/build.gradle`
|
|
||||||
```groovy
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3) Setup Firebase
|
|
||||||
|
|
||||||
Now you need to 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:
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
dependencies {
|
|
||||||
// This should be added already
|
|
||||||
compile(project(':react-native-firebase')) {
|
|
||||||
transitive = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// RNFirebase required dependencies
|
|
||||||
compile "com.google.firebase:firebase-core:11.4.2"
|
|
||||||
compile "com.google.android.gms:play-services-base:11.4.2"
|
|
||||||
|
|
||||||
// RNFirebase optional dependencies
|
|
||||||
compile "com.google.firebase:firebase-ads:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-auth:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-config:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-crash:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-database:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-firestore:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-invites:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-messaging:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-perf:11.4.2"
|
|
||||||
compile "com.google.firebase:firebase-storage:11.4.2"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Google Play services from 11.2.0 onwards require their dependencies to be downloaded from Google's Maven respository so add the
|
|
||||||
required reference to the repositories section of the *project* level build.gradle
|
|
||||||
`android/build.gradle`
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
jcenter()
|
|
||||||
maven {
|
|
||||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
||||||
url "$rootDir/../node_modules/react-native/android"
|
|
||||||
}
|
|
||||||
// -------------------------------------------------
|
|
||||||
// Add this below the existing maven property above
|
|
||||||
// -------------------------------------------------
|
|
||||||
maven {
|
|
||||||
url 'https://maven.google.com'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4) Install RNFirebase modules
|
|
||||||
|
|
||||||
RNFirebase is split into separate modules to allow you to only include the Firebase functionality that you need in your application.
|
|
||||||
|
|
||||||
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; // <-- This should be added already
|
|
||||||
// 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.firestore.RNFirebaseFirestorePackage; // Firebase Firestore
|
|
||||||
import io.invertase.firebase.links.RNFirebaseLinksPackage; // Firebase Links
|
|
||||||
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(), // <-- This should be added already
|
|
||||||
// Add these packages as appropriate
|
|
||||||
new RNFirebaseAdMobPackage(),
|
|
||||||
new RNFirebaseAnalyticsPackage(),
|
|
||||||
new RNFirebaseAuthPackage(),
|
|
||||||
new RNFirebaseRemoteConfigPackage(),
|
|
||||||
new RNFirebaseCrashPackage(),
|
|
||||||
new RNFirebaseDatabasePackage(),
|
|
||||||
new RNFirebaseFirestorePackage(),
|
|
||||||
new RNFirebaseLinksPackage(),
|
|
||||||
new RNFirebaseMessagingPackage(),
|
|
||||||
new RNFirebasePerformancePackage(),
|
|
||||||
new RNFirebaseStoragePackage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 5) 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>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6) 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:
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
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:
|
|
||||||
```groovy
|
|
||||||
apply plugin: "com.android.application"
|
|
||||||
apply plugin: "com.google.firebase.firebase-perf"
|
|
||||||
```
|
|
||||||
|
|
||||||
In the same file, add the `firebase-perf` module to your dependencies:
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
dependencies {
|
|
||||||
// ...
|
|
||||||
compile "com.google.firebase:firebase-perf:11.4.2"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 7) Dynamic Links (optional)
|
|
||||||
|
|
||||||
If you plan on using [Firebase Dynamic
|
|
||||||
Links](https://firebase.google.com/docs/dynamic-links/):
|
|
||||||
|
|
||||||
Make sure to setup dynamic links for Android as described [here](https://firebase.google.com/docs/dynamic-links/android/receive#set-up-firebase-and-the-dynamic-links-sdk)
|
|
||||||
|
|
||||||
In `android/app/src/main/AndroidManifest.xml`, add a new intent filter to the activity that handles deep links for your app (for react-native this is usually MainActivity), and specify the host and the scheme:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
|
||||||
<category android:name="android.intent.category.BROWSABLE"/>
|
|
||||||
<data android:host="yoursite.example.com" android:scheme="http"/>
|
|
||||||
<data android:host="yoursite.example.com" android:scheme="https"/>
|
|
||||||
</intent-filter>
|
|
||||||
```
|
|
|
@ -1,239 +0,0 @@
|
||||||
# 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) Link RNFirebase
|
|
||||||
|
|
||||||
Run `react-native link react-native-firebase`
|
|
||||||
|
|
||||||
## 2) 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).
|
|
||||||
|
|
||||||
Adding the file into the directory doesn't automatically add the file to the iOS project. You need to then manually add it by doing the following:
|
|
||||||
|
|
||||||
- 2.1. Open `<project root>/ios/'project name'.xcworkspace` file via XCode
|
|
||||||
- 2.1.1. If you've not got a `.xcworkspace` file yet then you'll need to come back to these steps after setting up your pods + pod install (step 3 on this page)
|
|
||||||
- 2.2. Right click on your project
|
|
||||||
- 2.3. Click "Add files to 'project name'"
|
|
||||||
- 2.4. Select the .plist file you copied into your project
|
|
||||||
- 2.5. Click OK
|
|
||||||
|
|
||||||
### 2.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];`
|
|
||||||
|
|
||||||
## 3) Setup Firebase Pods
|
|
||||||
|
|
||||||
Firebase recommends using Cocoapods to install the Firebase SDK.
|
|
||||||
|
|
||||||
### 3.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
|
|
||||||
|
|
||||||
### 3.1) Check the Podfile platform version
|
|
||||||
We recommend using a minimum platform version of at least 9.0 for your application to ensure that the correct version of the Firebase libraries are used. To do this, you need to uncomment or make sure the following line is present at the top of your `Podfile`:
|
|
||||||
|
|
||||||
`platform :ios, '9.0'`
|
|
||||||
|
|
||||||
### 3.2) 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'
|
|
||||||
|
|
||||||
# [OPTIONAL PODS] - comment out pods for firebase products you won't be using.
|
|
||||||
pod 'Firebase/AdMob'
|
|
||||||
pod 'Firebase/Auth'
|
|
||||||
pod 'Firebase/Crash'
|
|
||||||
pod 'Firebase/Database'
|
|
||||||
pod 'Firebase/DynamicLinks'
|
|
||||||
pod 'Firebase/Firestore'
|
|
||||||
pod 'Firebase/Messaging'
|
|
||||||
pod 'Firebase/RemoteConfig'
|
|
||||||
pod 'Firebase/Storage'
|
|
||||||
```
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
## 4) 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.**
|
|
||||||
|
|
||||||
### 4.1) Set up certificates
|
|
||||||
|
|
||||||
Follow the instructions at https://firebase.google.com/docs/cloud-messaging/ios/certs
|
|
||||||
|
|
||||||
### 4.2) Enable capabilities
|
|
||||||
|
|
||||||
In Xcode, enable the following capabilities:
|
|
||||||
|
|
||||||
1) Push Notifications
|
|
||||||
2) Background modes > Remote notifications
|
|
||||||
|
|
||||||
### 4.3) Update `AppDelegate.h`
|
|
||||||
|
|
||||||
Add the following import:
|
|
||||||
|
|
||||||
`@import UserNotifications;`
|
|
||||||
|
|
||||||
Change the interface descriptor to:
|
|
||||||
|
|
||||||
`@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>`
|
|
||||||
|
|
||||||
### 4.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];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4.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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 5) Dynamic Links (optional)
|
|
||||||
|
|
||||||
If you plan on using [Firebase Dynamic Links](https://firebase.google.com/docs/dynamic-links/) then, you need to:
|
|
||||||
|
|
||||||
### 5.1) Setup
|
|
||||||
|
|
||||||
Make sure to setup dynamic links for iOS as described [here](https://firebase.google.com/docs/dynamic-links/ios/receive#set-up-firebase-and-the-dynamic-links-sdk)
|
|
||||||
|
|
||||||
### 5.2) create a new URL type
|
|
||||||
|
|
||||||
In the Info tab of your app's Xcode project, create a new URL type to be used for Dynamic Links. Set the Identifier field to a unique value and the URL scheme field to either your bundle identifier or a unique value.
|
|
||||||
|
|
||||||
### 5.3) Enable Associated Domains capability
|
|
||||||
|
|
||||||
In the Capabilities tab of your app's Xcode project, enable Associated Domains and
|
|
||||||
add the following to the Associated Domains list:
|
|
||||||
`applinks:app_code.app.goo.gl` where `app_code` is your dynamic links domain application code.
|
|
||||||
|
|
||||||
### 5.4) Update `AppDelegate.m`
|
|
||||||
|
|
||||||
Add the following import:
|
|
||||||
|
|
||||||
`#import "RNFirebaseLinks.h"`
|
|
||||||
|
|
||||||
Add the following to the `didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` method before `[FIRApp Configure]`:
|
|
||||||
|
|
||||||
`[FIROptions defaultOptions].deepLinkURLScheme = CUSTOM_URL_SCHEME;`
|
|
||||||
where `CUSTOM_URL_SCHEME` is the custom URL scheme you defined in your Xcode project.
|
|
||||||
|
|
||||||
In the application:openURL:sourceApplication:annotation: (for iOS 8 and older) add the following:
|
|
||||||
|
|
||||||
```objectivec
|
|
||||||
- (BOOL)application:(UIApplication *)app
|
|
||||||
openURL:(NSURL *)url
|
|
||||||
options:(NSDictionary<NSString *, id> *)options {
|
|
||||||
return [RNFirebaseLinks application:application
|
|
||||||
openURL:url
|
|
||||||
options:options];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In the application:openURL:options: (for iOS 9) add the following:
|
|
||||||
|
|
||||||
```objectivec
|
|
||||||
- (BOOL)application:(UIApplication *)application
|
|
||||||
openURL:(NSURL *)url
|
|
||||||
sourceApplication:(NSString *)sourceApplication
|
|
||||||
annotation:(id)annotation {
|
|
||||||
return [RNFirebaseLinks application:application
|
|
||||||
openURL:url
|
|
||||||
sourceApplication:sourceApplication
|
|
||||||
annotation:annotation];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In the application:continueUserActivity:restorationHandler (Universal Links on iOS 9 and newer) add the following:
|
|
||||||
|
|
||||||
```objectivec
|
|
||||||
- (BOOL)application:(UIApplication *)application
|
|
||||||
continueUserActivity:(NSUserActivity *)userActivity
|
|
||||||
restorationHandler:(void (^)(NSArray *))restorationHandler {
|
|
||||||
return [RNFirebaseLinks application:application
|
|
||||||
continueUserActivity:userActivity
|
|
||||||
restorationHandler:restorationHandler];
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,100 +0,0 @@
|
||||||
# Migration
|
|
||||||
|
|
||||||
## From v2 to v3
|
|
||||||
|
|
||||||
The below is a quick summary of steps to take when migrating from v2 to v3 of RNFirebase. Please see the [v3 change log](https://github.com/invertase/react-native-firebase/releases/tag/v3.0.0) for detailed changes.
|
|
||||||
|
|
||||||
** Please note, we're now using `Apache License 2.0` to license this library. **
|
|
||||||
|
|
||||||
##### 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.48):
|
|
||||||
|
|
||||||
- Follow the instructions [here](https://facebook.github.io/react-native/docs/upgrading.html)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### 3) Update your code to reflect deprecations/breaking changes if needed:
|
|
||||||
|
|
||||||
- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) **[breaking]** [database] enabling database persistence (setPersistence) via JS is no longer supported - this is to prevent several race conditions. See sub points on how to enable these natively.
|
|
||||||
- [android] add `FirebaseDatabase.getInstance().setPersistenceEnabled(true);` to your `MainActivity` `onCreate` method.
|
|
||||||
- [ios] add `[FIRDatabase database].persistenceEnabled = YES;` after the `[FIRApp configure];` line inside your `AppDelegate` `didFinishLaunchingWithOptions` method.
|
|
||||||
- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) **[breaking]** [app] `new RNFirebase()` is no longer supported. See below for information about app initialisation.
|
|
||||||
- ![#f03c15](https://placehold.it/15/fdfd96/000000?text=+) **[deprecated]** [app] `initializeApp()` for apps that are already initialised natively (i.e. the default app initialised via google-services plist/json) will now log a deprecation warning.
|
|
||||||
- As these apps are already initialised natively there's no need to call `initializeApp` in your JS code. For now, calling it will just return the app that's already internally initialised - in a future version this will throw an `already initialized` exception.
|
|
||||||
- Accessing apps can now be done the same way as the web sdk, simply call `firebase.app()` to get the default app, or with the name of specific app as the first arg, e.g. `const meow = firebase.app('catsApp');` to get a specific app.
|
|
||||||
- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) **[breaking]** [auth] Third party providers now user `providerId` rather than `provider` as per the Web SDK. If you are manually creating your credentials, you will need to update the field name.
|
|
||||||
- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) **[breaking]** [database] Error messages and codes internally re-written to match the web sdk
|
|
||||||
- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) **[breaking]** [database] `ref.isEqual` now checks the query modifiers as well as the ref path (was just path before). With the release of multi apps/core support this check now also includes whether the refs are for the same app.
|
|
||||||
- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) **[breaking]** [database] on/off behaviour changes. Previous `off` behaviour was incorrect. A `SyncTree/Repo` implementation was added to provide the correct behaviour you'd expect in the web sdk. Whilst this is a breaking change it shouldn't be much of an issue if you've previously setup your on/off handling correctly. See #160 for specifics of this change.
|
|
||||||
- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) **[breaking]** [storage] UploadTaskSnapshot -> `downloadUrl` renamed to `downloadURL` to match web sdk
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### 4) Android - Update `android/build.gradle`:
|
|
||||||
|
|
||||||
|
|
||||||
- Check you are using google-services 3.1.0 or greater:
|
|
||||||
- You must add `maven { url 'https://maven.google.com' }` to your `android/build.gradle` as follows:
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
|
||||||
classpath 'com.google.gms:google-services:3.1.0' // CHECK VERSION HERE
|
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
|
||||||
// in the individual module build.gradle files
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
jcenter()
|
|
||||||
maven {
|
|
||||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
||||||
url "$rootDir/../node_modules/react-native/android"
|
|
||||||
}
|
|
||||||
// -------------------------------------------------
|
|
||||||
// Add this below the existing maven property above
|
|
||||||
// -------------------------------------------------
|
|
||||||
maven {
|
|
||||||
url 'https://maven.google.com'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### 5) Android - Update `app/build.gradle`:
|
|
||||||
|
|
||||||
|
|
||||||
- You must update all your Firebase & play services dependencies to 11.4.2.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### 6) iOS - Update podfile:
|
|
||||||
|
|
||||||
- You need to check that you're running at least version 4.3.0 of the Firebase Pods
|
|
||||||
- Run `pod outdated`
|
|
||||||
- Run `pod update`
|
|
||||||
|
|
||||||
Add the `Firebase/Firestore` if you plan on using firestore.
|
|
||||||
|
|
||||||
## From v1 to v2
|
|
||||||
|
|
||||||
See the guide on the [v2 docs](/v2/migration-guide?id=migration)
|
|
|
@ -1,382 +0,0 @@
|
||||||
# AdMob
|
|
||||||
|
|
||||||
The admob module 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 device’s 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.
|
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
# 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');
|
|
||||||
```
|
|
|
@ -1,324 +0,0 @@
|
||||||
# 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}`);
|
|
||||||
});
|
|
||||||
```
|
|
|
@ -1,159 +0,0 @@
|
||||||
# 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);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### deleteInstanceId(): `Promise<any>`
|
|
||||||
|
|
||||||
Reset Instance ID and revokes all tokens.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
firebase.messaging().deleteInstanceId()
|
|
||||||
.then(() => {
|
|
||||||
console.log('Deleted instance id successfully');
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
console.log(`Cannot delete instance id: ${error.message}`);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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);
|
|
||||||
});
|
|
||||||
```
|
|
|
@ -1,149 +0,0 @@
|
||||||
# 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);
|
|
||||||
```
|
|
|
@ -1,54 +0,0 @@
|
||||||
# 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)`.
|
|
|
@ -1,204 +0,0 @@
|
||||||
|
|
||||||
# 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.
|
|
|
@ -1,192 +0,0 @@
|
||||||
|
|
||||||
# Firestore (Beta)
|
|
||||||
|
|
||||||
RNFirebase mimics the [Firestore Web SDK](https://firebase.google.com/docs/reference/js/firebase.firestore) by providing a bridge to the native Android and iOS Firestore SDK's.
|
|
||||||
|
|
||||||
All Firestore operations are accessed via `firebase.firestore()`. For detailed documentation of the supported methods demonstrated below please use the official firestore web sdk guides.
|
|
||||||
|
|
||||||
?> Please note that Persistence (offline support) is enabled by default with Firestore on iOS and Android.
|
|
||||||
|
|
||||||
## Add and Manage Data
|
|
||||||
|
|
||||||
### Collections
|
|
||||||
|
|
||||||
Read information about a collection example:
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.collection('posts')
|
|
||||||
.get()
|
|
||||||
.then(querySnapshot => {
|
|
||||||
// Access all the documents in the collection
|
|
||||||
const docs = querySnapshot.docs;
|
|
||||||
// Access the list of document changes for the collection
|
|
||||||
const changes = querySnapshot.docChanges;
|
|
||||||
// Loop through the documents
|
|
||||||
querySnapshot.forEach((doc) => {
|
|
||||||
const value = doc.data();
|
|
||||||
})
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Add to a collection example (generated ID):
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.collection('posts')
|
|
||||||
.add({
|
|
||||||
title: 'Amazing post',
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// Document added to collection and ID generated
|
|
||||||
// Will have path: `posts/{generatedId}`
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Add to a collection example (manual ID):
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.collection('posts')
|
|
||||||
.doc('post1')
|
|
||||||
.set({
|
|
||||||
title: 'My awesome post',
|
|
||||||
content: 'Some awesome content',
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// Document added to collection with path: `posts/post1`
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
### Documents
|
|
||||||
|
|
||||||
There are multiple ways to read a document. The following are equivalent examples:
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.doc('posts/posts1')
|
|
||||||
.get()
|
|
||||||
.then((documentSnapshot) => {
|
|
||||||
const value = documentSnapshot.data();
|
|
||||||
});
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.collection('posts')
|
|
||||||
.doc('posts1')
|
|
||||||
.get()
|
|
||||||
.then((documentSnapshot) => {
|
|
||||||
const value = documentSnapshot.data();
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Create a document example:
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.doc('posts/posts1')
|
|
||||||
.set({
|
|
||||||
title: 'My awesome post',
|
|
||||||
content: 'Some awesome content',
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// Document created
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Updating a document example:
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.doc('posts/posts1')
|
|
||||||
.update({
|
|
||||||
title: 'My awesome post',
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
// Document created
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Deleting a document example:
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.doc('posts/posts1')
|
|
||||||
.delete()
|
|
||||||
.then(() => {
|
|
||||||
// Document deleted
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Batching document updates
|
|
||||||
|
|
||||||
Writes, updates and deletes to documents can be batched and committed atomically as follows:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
const ayRef = firebase.firestore().doc('places/AY');
|
|
||||||
const lRef = firebase.firestore().doc('places/LON');
|
|
||||||
const nycRef = firebase.firestore().doc('places/NYC');
|
|
||||||
const sfRef = firebase.firestore().doc('places/SF');
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.batch()
|
|
||||||
.set(ayRef, { name: 'Aylesbury' })
|
|
||||||
.set(lRef, { name: 'London' })
|
|
||||||
.set(nycRef, { name: 'New York City' })
|
|
||||||
.set(sfRef, { name: 'San Francisco' })
|
|
||||||
.update(nycRef, { population: 1000000 })
|
|
||||||
.update(sfRef, { name: 'San Fran' })
|
|
||||||
.set(lRef, { population: 3000000 }, { merge: true })
|
|
||||||
.delete(ayRef)
|
|
||||||
.commit()
|
|
||||||
.then(() => {
|
|
||||||
// Would end up with three documents in the collection: London, New York City and San Francisco
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Transactions
|
|
||||||
|
|
||||||
Coming soon
|
|
||||||
|
|
||||||
## Realtime Updates
|
|
||||||
|
|
||||||
### Collections
|
|
||||||
|
|
||||||
Listen to collection updates example:
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.collection('cities')
|
|
||||||
.where('state', '==', 'CA')
|
|
||||||
.onSnapshot((querySnapshot) => {
|
|
||||||
querySnapshot.forEach((doc) => {
|
|
||||||
// DocumentSnapshot available
|
|
||||||
})
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
The snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified).
|
|
||||||
|
|
||||||
### Documents
|
|
||||||
|
|
||||||
Listen to document updates example:
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.firestore()
|
|
||||||
.doc('posts/post1')
|
|
||||||
.onSnapshot((documentSnapshot) => {
|
|
||||||
// DocumentSnapshot available
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
The snapshot handler will receive the current contents of the document, and any subsequent changes to the document.
|
|
|
@ -1,123 +0,0 @@
|
||||||
# Dynamic Links
|
|
||||||
|
|
||||||
[Firebase Dynamic Links](https://firebase.google.com/docs/dynamic-links/) allows you to create and receive links on both Android and iOS platforms. Assuming the installation instructions have been followed, Firebase Dynamic Links is ready to go.
|
|
||||||
|
|
||||||
|
|
||||||
All Dynamic Links operations are accessed via `firebase.links()`
|
|
||||||
|
|
||||||
## Create Dynamic Links
|
|
||||||
|
|
||||||
RNFirebase mimics [Firebase's REST API](https://firebase.google.com/docs/dynamic-links/rest) for Dynamic Links creation.
|
|
||||||
The differences from the REST API are:
|
|
||||||
1. The input for the methods is a javascript object instead of a JSON object.
|
|
||||||
2. The response contains the URL string only.
|
|
||||||
3. There is no `dynamicLinkInfo` element. Instead, all of the elements under it were moved to be under the top-level.
|
|
||||||
|
|
||||||
### Methods
|
|
||||||
|
|
||||||
#### `createDynamicLink(parameters: Object): Promise<String>`
|
|
||||||
|
|
||||||
Creates a long dynamic link.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
firebase.links().createDynamicLink({
|
|
||||||
dynamicLinkDomain: "abc123.app.goo.gl",
|
|
||||||
link: "https://example.com?param1=foo¶m2=bar",
|
|
||||||
androidInfo: {
|
|
||||||
androidPackageName: "com.example.android"
|
|
||||||
},
|
|
||||||
iosInfo: {
|
|
||||||
iosBundleId: "com.example.ios"
|
|
||||||
}
|
|
||||||
}).
|
|
||||||
then((url) => {
|
|
||||||
// ...
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `createShortDynamicLink(parameters: Object): Promise<String>`
|
|
||||||
|
|
||||||
Creates a short dynamic link.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
firebase.links().createShortDynamicLink({
|
|
||||||
dynamicLinkDomain: "abc123.app.goo.gl",
|
|
||||||
link: "https://example.com?param1=foo¶m2=bar",
|
|
||||||
androidInfo: {
|
|
||||||
androidPackageName: "com.example.android"
|
|
||||||
},
|
|
||||||
iosInfo: {
|
|
||||||
iosBundleId: "com.example.ios"
|
|
||||||
}
|
|
||||||
}).
|
|
||||||
then((url) => {
|
|
||||||
// ...
|
|
||||||
});
|
|
||||||
```
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
Only the following parameters are currently supported:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
dynamicLinkDomain: 'string',
|
|
||||||
link: 'string',
|
|
||||||
androidInfo: {
|
|
||||||
androidPackageName: 'string',
|
|
||||||
androidFallbackLink: 'string',
|
|
||||||
androidMinPackageVersionCode: 'string',
|
|
||||||
androidLink: 'string',
|
|
||||||
},
|
|
||||||
iosInfo: {
|
|
||||||
iosBundleId: 'string',
|
|
||||||
iosFallbackLink: 'string',
|
|
||||||
iosCustomScheme: 'string',
|
|
||||||
iosIpadFallbackLink: 'string',
|
|
||||||
iosIpadBundleId: 'string',
|
|
||||||
iosAppStoreId: 'string',
|
|
||||||
},
|
|
||||||
socialMetaTagInfo: {
|
|
||||||
socialTitle: 'string',
|
|
||||||
socialDescription: 'string',
|
|
||||||
socialImageLink: 'string',
|
|
||||||
},
|
|
||||||
suffix: {
|
|
||||||
option: 'string',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
```
|
|
||||||
**please note:**
|
|
||||||
1. dynamicLinkDomain and link are mandatory fields. In addition, when using `androidInfo` or `iosInfo`, `androidPackageName` and `iosBundleId` are mandatory (respectively).
|
|
||||||
2. In oppose to the REST API, There is no `dynamicLinkInfo` element. Instead, all of the elements under it were moved to be under the top-level.
|
|
||||||
|
|
||||||
For more information [see reference](https://firebase.google.com/docs/reference/dynamic-links/link-shortener)
|
|
||||||
|
|
||||||
## Receive Dynamic Links
|
|
||||||
|
|
||||||
### Methods
|
|
||||||
|
|
||||||
#### `getInitialLink(): Promise<String>`
|
|
||||||
|
|
||||||
Call getInitialLink to access the URL that the app has been launched from. If the app was not launched from a URL, the return value is null.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
firebase.links().getInitialLink().then((url) => {
|
|
||||||
//...
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `onLink(listener: Function<String>): Function`
|
|
||||||
|
|
||||||
On a new URL, the payload URL is passed to the listener callback. This method is only triggered when the app is running. Use getInitialLink for URLs which cause the app to open.
|
|
||||||
In order to subscribe to the listener, call to the method with a callback and save the returned function.
|
|
||||||
When you want to unsubscribe, just call the function that returned at subscription.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Subscribe
|
|
||||||
const unsubscribe = firebase.links().onLink((url) => {
|
|
||||||
//...
|
|
||||||
});
|
|
||||||
|
|
||||||
// Unsubscribe
|
|
||||||
unsubscribe();
|
|
||||||
```
|
|
|
@ -1,64 +0,0 @@
|
||||||
# Performance Monitoring
|
|
||||||
|
|
||||||
?> 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();
|
|
||||||
```
|
|
|
@ -1,100 +0,0 @@
|
||||||
# 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()
|
|
|
@ -1,34 +0,0 @@
|
||||||
# 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());
|
|
||||||
});
|
|
||||||
```
|
|
334
docs/redux.md
334
docs/redux.md
|
@ -1,334 +0,0 @@
|
||||||
# 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).
|
|
||||||
|
|
||||||
## 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);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## React Redux Firebase
|
|
||||||
|
|
||||||
[`react-redux-firebase`](http://docs.react-redux-firebase.com/history/v2.0.0) provides simplified and standardized common redux/firebase logic.
|
|
||||||
|
|
||||||
To add `react-redux-firebase` to your project:
|
|
||||||
1. Make sure you already have `redux`, `react-redux`, `redux-thunk` installed (if not, run `npm i --save redux react-redux redux-thunk`)
|
|
||||||
1. Run `npm i --save react-redux-firebase@canary` *we point to canary here to get current progress with v2.0.0*
|
|
||||||
1. Add `firebaseStateReducer` under `firebase` key within reducer:
|
|
||||||
|
|
||||||
**reducers.js**
|
|
||||||
```js
|
|
||||||
import { combineReducers } from 'redux';
|
|
||||||
import { firebaseStateReducer } from 'react-redux-firebase';
|
|
||||||
|
|
||||||
export const makeRootReducer = (asyncReducers) => {
|
|
||||||
return combineReducers({
|
|
||||||
// Add sync reducers here
|
|
||||||
firebase: firebaseStateReducer,
|
|
||||||
...asyncReducers
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default makeRootReducer;
|
|
||||||
|
|
||||||
// *Optional* Useful for injecting reducers as part of async routes
|
|
||||||
export const injectReducer = (store, { key, reducer }) => {
|
|
||||||
store.asyncReducers[key] = reducer
|
|
||||||
store.replaceReducer(makeRootReducer(store.asyncReducers))
|
|
||||||
};
|
|
||||||
```
|
|
||||||
1. Pass `react-native-firebase` App instance into `reactReduxFirebase` when creating store:
|
|
||||||
|
|
||||||
**createStore.js**
|
|
||||||
```js
|
|
||||||
import { applyMiddleware, compose, createStore } from 'redux';
|
|
||||||
import RNFirebase from 'react-native-firebase';
|
|
||||||
import { getFirebase, reactReduxFirebase } from 'react-redux-firebase';
|
|
||||||
import thunk from 'redux-thunk';
|
|
||||||
import makeRootReducer from './reducers';
|
|
||||||
|
|
||||||
const reactNativeFirebaseConfig = {
|
|
||||||
debug: true
|
|
||||||
};
|
|
||||||
// for more config options, visit http://docs.react-redux-firebase.com/history/v2.0.0/docs/api/compose.html
|
|
||||||
const reduxFirebaseConfig = {
|
|
||||||
userProfile: 'users', // save users profiles to 'users' collection
|
|
||||||
};
|
|
||||||
|
|
||||||
export default (initialState = { firebase: {} }) => {
|
|
||||||
// initialize firebase
|
|
||||||
const firebase = RNFirebase.initializeApp(reactNativeFirebaseConfig);
|
|
||||||
|
|
||||||
const store = createStore(
|
|
||||||
makeRootReducer(),
|
|
||||||
initialState,
|
|
||||||
compose(
|
|
||||||
reactReduxFirebase(firebase, reduxFirebaseConfig), // pass initialized react-native-firebase app instance
|
|
||||||
// applyMiddleware(...middleware) // if using middleware
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return store;
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Wrap in `Provider` from `react-redux`:
|
|
||||||
|
|
||||||
**index.js**
|
|
||||||
```js
|
|
||||||
import React from 'react';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
import createStore from './createStore';
|
|
||||||
import Home from './Home';
|
|
||||||
|
|
||||||
// Store Initialization
|
|
||||||
const initialState = { firebase: {} };
|
|
||||||
let store = createStore(initialState);
|
|
||||||
|
|
||||||
const Main = () => (
|
|
||||||
<Provider store={store}>
|
|
||||||
<Home />
|
|
||||||
</Provider>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default Main;
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Then you can use the `firebaseConnect` HOC to wrap your components. It makes it easy to set listeners which gather data from Firebase and place it into redux:
|
|
||||||
|
|
||||||
**Home.js**
|
|
||||||
```js
|
|
||||||
import React from 'react';
|
|
||||||
import { compose } from 'redux';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { isLoaded, isEmpty, firebaseConnect } from 'react-redux-firebase';
|
|
||||||
import { View, Text, StyleSheet, ActivityIndicator } from 'react-native';
|
|
||||||
import NewTodo from './NewTodo';
|
|
||||||
import Todos from './Todos';
|
|
||||||
|
|
||||||
class Home extends React.Component {
|
|
||||||
state = {
|
|
||||||
text: null
|
|
||||||
}
|
|
||||||
|
|
||||||
completeTodo = (key, todo) => {
|
|
||||||
return this.props.firebase.update(`todos/${key}`, { done: !todo.done })
|
|
||||||
}
|
|
||||||
|
|
||||||
addTodo = () => {
|
|
||||||
const { text } = this.state;
|
|
||||||
return this.props.firebase.push('todos', { text, completed: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { todos } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View>
|
|
||||||
<Text>Todos</Text>
|
|
||||||
<NewTodo
|
|
||||||
onNewTouch={this.addTodo}
|
|
||||||
newValue={this.state.text}
|
|
||||||
onInputChange={(v) => this.setState({text: v})}
|
|
||||||
/>
|
|
||||||
{
|
|
||||||
!isLoaded(todos)
|
|
||||||
? <ActivityIndicator size="large" style={{ marginTop: 100 }}/>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
{
|
|
||||||
isLoaded(todos) && !isEmpty(todos)
|
|
||||||
?
|
|
||||||
<Todos
|
|
||||||
todos={todos}
|
|
||||||
onItemTouch={this.completeTodo}
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
<View style={styles.container}>
|
|
||||||
<Text>No Todos Found</Text>
|
|
||||||
</View>
|
|
||||||
}
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default compose(
|
|
||||||
firebaseConnect([
|
|
||||||
// create listener for firebase data -> redux
|
|
||||||
{ path: 'todos', queryParams: ['limitToLast=15'] }
|
|
||||||
]),
|
|
||||||
connect((state) => ({
|
|
||||||
// todos: state.firebase.data.todos, // todos data object from redux -> props.todos
|
|
||||||
todos: state.firebase.ordered.todos, // todos ordered array from redux -> props.todos
|
|
||||||
}))
|
|
||||||
)(Home);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Todos.js**
|
|
||||||
```js
|
|
||||||
import React from 'react'
|
|
||||||
import {
|
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
StyleSheet,
|
|
||||||
FlatList,
|
|
||||||
TouchableHighlight
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
const Todos = ({ todos, onItemTouch }) => (
|
|
||||||
<FlatList
|
|
||||||
data={todos.reverse()}
|
|
||||||
renderItem={({ item: { key, value } }) => (
|
|
||||||
<TouchableHighlight onPress={() => onItemTouch(key, value)}>
|
|
||||||
<View>
|
|
||||||
<Text>{value.text}</Text>
|
|
||||||
<Text>Done: {value.done === true ? 'True' : 'False'}</Text>
|
|
||||||
</View>
|
|
||||||
</TouchableHighlight>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default Todos;
|
|
||||||
```
|
|
||||||
Notice how `connect` is still used to get data out of `redux` since `firebaseConnect` only loads data **into** redux.
|
|
||||||
|
|
||||||
Full source with styling available [in the react-native-firebase example for react-redux-firebase](https://github.com/prescottprue/react-redux-firebase/tree/v2.0.0/examples/complete/react-native-firebase)
|
|
||||||
|
|
||||||
For more details, please visit [`react-redux-firebase`'s react-native section](http://docs.react-redux-firebase.com/history/v2.0.0/docs/recipes/react-native.html#native-modules).
|
|
||||||
|
|
||||||
#### Thunks
|
|
||||||
`react-redux-firebase` provides the `getFirebase` helper for easy access to Firebase helper methods. Using this feature is as easy as passing it in while creating your store:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const middleware = [
|
|
||||||
// make getFirebase available in third argument of thunks
|
|
||||||
thunk.withExtraArgument({ getFirebase }),
|
|
||||||
];
|
|
||||||
|
|
||||||
const store = createStore(
|
|
||||||
makeRootReducer(),
|
|
||||||
initialState,
|
|
||||||
compose(
|
|
||||||
reactReduxFirebase(firebase, reduxFirebaseConfig),
|
|
||||||
applyMiddleware(...middleware) // pass in middleware
|
|
||||||
)
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
75
docs/sw.js
75
docs/sw.js
|
@ -1,75 +0,0 @@
|
||||||
const RUNTIME = 'docsify'
|
|
||||||
const HOSTNAME_WHITELIST = [
|
|
||||||
self.location.hostname,
|
|
||||||
'fonts.gstatic.com',
|
|
||||||
'fonts.googleapis.com',
|
|
||||||
'unpkg.com'
|
|
||||||
]
|
|
||||||
|
|
||||||
// The Util Function to hack URLs of intercepted requests
|
|
||||||
const getFixedUrl = (req) => {
|
|
||||||
var now = Date.now()
|
|
||||||
var url = new URL(req.url)
|
|
||||||
|
|
||||||
// 1. fixed http URL
|
|
||||||
// Just keep syncing with location.protocol
|
|
||||||
// fetch(httpURL) belongs to active mixed content.
|
|
||||||
// And fetch(httpRequest) is not supported yet.
|
|
||||||
url.protocol = self.location.protocol
|
|
||||||
|
|
||||||
// 2. add query for caching-busting.
|
|
||||||
// Github Pages served with Cache-Control: max-age=600
|
|
||||||
// max-age on mutable content is error-prone, with SW life of bugs can even extend.
|
|
||||||
// Until cache mode of Fetch API landed, we have to workaround cache-busting with query string.
|
|
||||||
// Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190
|
|
||||||
if (url.hostname === self.location.hostname) {
|
|
||||||
url.search += (url.search ? '&' : '?') + 'cache-bust=' + now
|
|
||||||
}
|
|
||||||
return url.href
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Lifecycle Activate
|
|
||||||
* New one activated when old isnt being used.
|
|
||||||
*
|
|
||||||
* waitUntil(): activating ====> activated
|
|
||||||
*/
|
|
||||||
self.addEventListener('activate', event => {
|
|
||||||
event.waitUntil(self.clients.claim())
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Functional Fetch
|
|
||||||
* All network requests are being intercepted here.
|
|
||||||
*
|
|
||||||
* void respondWith(Promise<Response> r)
|
|
||||||
*/
|
|
||||||
self.addEventListener('fetch', event => {
|
|
||||||
// Skip some of cross-origin requests, like those for Google Analytics.
|
|
||||||
if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) {
|
|
||||||
// Stale-while-revalidate
|
|
||||||
// similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale
|
|
||||||
// Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1
|
|
||||||
const cached = caches.match(event.request)
|
|
||||||
const fixedUrl = getFixedUrl(event.request)
|
|
||||||
const fetched = fetch(fixedUrl, { cache: 'no-store' })
|
|
||||||
const fetchedCopy = fetched.then(resp => resp.clone())
|
|
||||||
|
|
||||||
// Call respondWith() with whatever we get first.
|
|
||||||
// If the fetch fails (e.g disconnected), wait for the cache.
|
|
||||||
// If there’s nothing in cache, wait for the fetch.
|
|
||||||
// If neither yields a response, return offline pages.
|
|
||||||
event.respondWith(
|
|
||||||
Promise.race([fetched.catch(_ => cached), cached])
|
|
||||||
.then(resp => resp || fetched)
|
|
||||||
.catch(_ => { /* eat any errors */ })
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update the cache with the version we fetched (only for ok status)
|
|
||||||
event.waitUntil(
|
|
||||||
Promise.all([fetchedCopy, caches.open(RUNTIME)])
|
|
||||||
.then(([response, cache]) => response.ok && cache.put(event.request, response))
|
|
||||||
.catch(_ => { /* eat any errors */ })
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Usage
|
|
||||||
|
|
||||||
After creating a Firebase project and installing the library, you can then use it in your project by importing the library in your JavaScript code:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
```
|
|
||||||
|
|
||||||
As the default app is pre-initialized natively there is no need to call `initializeApp` for the default app instance. Just import and go:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import firebase from 'react-native-firebase';
|
|
||||||
|
|
||||||
firebase.auth().signInAnonymously()
|
|
||||||
.then((user) => {
|
|
||||||
console.log(user.isAnonymous);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configure Default App Instance
|
|
||||||
|
|
||||||
See [configure the default app instance](/core/config-default-app).
|
|
||||||
|
|
||||||
### Configuring RNFirebase
|
|
||||||
|
|
||||||
See [configure RNFirebase](/core/config-rnfirebase).
|
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
<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)
|
|
||||||
[![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 + |
|
|
|
@ -1,3 +0,0 @@
|
||||||
- <div class="version-select"><b>Version:</b> v2.x.x</div>
|
|
||||||
- [v3.x.x](/)
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) Viewing old RNFirebase version ![#f03c15](https://placehold.it/15/f03c15/000000?text=+)
|
|
||||||
|
|
||||||
- Getting started
|
|
||||||
- [Initial setup](/v2/initial-setup)
|
|
||||||
- [Installation - iOS](/v2/installation-ios)
|
|
||||||
- [Installation - Android](/v2/installation-android)
|
|
||||||
- [Usage](/v2/usage)
|
|
||||||
- [Migration Guide](/v2/migration-guide)
|
|
||||||
|
|
||||||
- Contributing
|
|
||||||
- [Guidelines](/v2/contributing/guidelines)
|
|
||||||
- [Testing](/v2/contributing/testing)
|
|
||||||
|
|
||||||
- Modules
|
|
||||||
- [Admob](/v2/modules/admob)
|
|
||||||
- [Analytics](/v2/modules/analytics)
|
|
||||||
- [Authentication](/v2/modules/authentication)
|
|
||||||
- [Cloud Messaging](/v2/modules/cloud-messaging)
|
|
||||||
- [Crash Reporting](/v2/modules/crash)
|
|
||||||
- [Database](/v2/modules/database)
|
|
||||||
- [Remote Config](/v2/modules/config)
|
|
||||||
- [Storage](/v2/modules/storage)
|
|
||||||
- [Transactions](/v2/modules/transactions)
|
|
||||||
- [Performance Monitoring](/v2/modules/perf)
|
|
||||||
|
|
||||||
- Other
|
|
||||||
- [Usage with Redux](/v2/redux)
|
|
||||||
- [Project Board](https://github.com/invertase/react-native-firebase/projects)
|
|
||||||
- [FAQs / Troubleshooting](/v2/faqs)
|
|
||||||
- [Examples](https://github.com/invertase/react-native-firebase-examples)
|
|
||||||
- [Chat](https://discord.gg/t6bdqMs)
|
|
|
@ -1,5 +0,0 @@
|
||||||
# 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.
|
|
|
@ -1,330 +0,0 @@
|
||||||
# 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
|
|
||||||
```
|
|
103
docs/v2/faqs.md
103
docs/v2/faqs.md
|
@ -1,103 +0,0 @@
|
||||||
# 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
|
|
|
@ -1,21 +0,0 @@
|
||||||
# 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).
|
|
|
@ -1,183 +0,0 @@
|
||||||
# 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-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.4"
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,163 +0,0 @@
|
||||||
# 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/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
|
|
|
@ -1,172 +0,0 @@
|
||||||
# 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.0.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.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"
|
|
||||||
```
|
|
||||||
Add each of the firebase modules you need from the following list:
|
|
||||||
```groovy
|
|
||||||
compile "com.google.firebase:firebase-ads: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"
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### 6) Android - Update `MainApplication.java`:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Update `MainApplication.java` and import the modules you require / currently use:
|
|
||||||
|
|
||||||
```java
|
|
||||||
// Required package
|
|
||||||
import io.invertase.firebase.RNFirebasePackage; // <-- Keep 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 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
|
|
||||||
// Add these 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
|
|
||||||
```
|
|
|
@ -1,382 +0,0 @@
|
||||||
# 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 device’s 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.
|
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
# 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');
|
|
||||||
```
|
|
|
@ -1,324 +0,0 @@
|
||||||
# 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}`);
|
|
||||||
});
|
|
||||||
```
|
|
|
@ -1,145 +0,0 @@
|
||||||
# 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);
|
|
||||||
});
|
|
||||||
```
|
|
|
@ -1,149 +0,0 @@
|
||||||
# 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);
|
|
||||||
```
|
|
|
@ -1,54 +0,0 @@
|
||||||
# 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)`.
|
|
|
@ -1,204 +0,0 @@
|
||||||
|
|
||||||
# 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.
|
|
|
@ -1,66 +0,0 @@
|
||||||
# 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();
|
|
||||||
```
|
|
|
@ -1,100 +0,0 @@
|
||||||
# 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()
|
|
|
@ -1,35 +0,0 @@
|
||||||
# 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
125
docs/v2/redux.md
|
@ -1,125 +0,0 @@
|
||||||
# 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);
|
|
||||||
```
|
|
|
@ -1,38 +0,0 @@
|
||||||
# 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;
|
|
||||||
```
|
|
Loading…
Reference in New Issue