diff --git a/app/containers/markdown/index.js b/app/containers/markdown/index.js
index d4435edea..40af9e171 100644
--- a/app/containers/markdown/index.js
+++ b/app/containers/markdown/index.js
@@ -60,6 +60,8 @@ const emojiCount = (str) => {
return counter;
};
+const parser = new Parser();
+
class Markdown extends PureComponent {
static propTypes = {
msg: PropTypes.string,
@@ -81,13 +83,9 @@ class Markdown extends PureComponent {
constructor(props) {
super(props);
-
- this.parser = this.createParser();
this.renderer = this.createRenderer(props.preview);
}
- createParser = () => new Parser();
-
createRenderer = (preview = false) => new Renderer({
renderers: {
text: this.renderText,
@@ -385,7 +383,7 @@ class Markdown extends PureComponent {
if (preview) {
m = m.split('\n').reduce((lines, line) => `${ lines } ${ line }`, '');
- const ast = this.parser.parse(m);
+ const ast = parser.parse(m);
return this.renderer.render(ast);
}
@@ -393,7 +391,7 @@ class Markdown extends PureComponent {
return {m};
}
- const ast = this.parser.parse(m);
+ const ast = parser.parse(m);
this.isMessageContainsOnlyEmoji = isOnlyEmoji(m) && emojiCount(m) <= 3;
this.editedMessage(ast);
diff --git a/app/index.js b/app/index.js
index 0f596f650..428a0c190 100644
--- a/app/index.js
+++ b/app/index.js
@@ -43,6 +43,9 @@ import Tablet, { initTabletNav } from './tablet';
import sharedStyles from './views/Styles';
import { SplitContext } from './split';
+import RoomsListView from './views/RoomsListView';
+import RoomView from './views/RoomView';
+
if (isIOS) {
const RNScreens = require('react-native-screens');
RNScreens.useScreens();
@@ -111,9 +114,7 @@ const OutsideStackModal = createStackNavigator({
});
const RoomRoutes = {
- RoomView: {
- getScreen: () => require('./views/RoomView').default
- },
+ RoomView,
ThreadMessagesView: {
getScreen: () => require('./views/ThreadMessagesView').default
},
@@ -127,9 +128,7 @@ const RoomRoutes = {
// Inside
const ChatsStack = createStackNavigator({
- RoomsListView: {
- getScreen: () => require('./views/RoomsListView').default
- },
+ RoomsListView,
RoomActionsView: {
getScreen: () => require('./views/RoomActionsView').default
},
diff --git a/app/lib/methods/subscriptions/rooms.js b/app/lib/methods/subscriptions/rooms.js
index 52f527d56..02fac22f3 100644
--- a/app/lib/methods/subscriptions/rooms.js
+++ b/app/lib/methods/subscriptions/rooms.js
@@ -1,4 +1,5 @@
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
+import { InteractionManager } from 'react-native';
import database from '../../database';
import { merge } from '../helpers/mergeSubscriptionsRooms';
@@ -23,7 +24,7 @@ let subQueue = {};
let subTimer = null;
let roomQueue = {};
let roomTimer = null;
-const WINDOW_TIME = 1000;
+const WINDOW_TIME = 500;
const createOrUpdateSubscription = async(subscription, room) => {
try {
@@ -176,7 +177,9 @@ const debouncedUpdateSub = (subscription) => {
subQueue = {};
subTimer = null;
Object.keys(subBatch).forEach((key) => {
- createOrUpdateSubscription(subBatch[key]);
+ InteractionManager.runAfterInteractions(() => {
+ createOrUpdateSubscription(subBatch[key]);
+ });
});
}, WINDOW_TIME);
}
@@ -190,7 +193,9 @@ const debouncedUpdateRoom = (room) => {
roomQueue = {};
roomTimer = null;
Object.keys(roomBatch).forEach((key) => {
- createOrUpdateSubscription(null, roomBatch[key]);
+ InteractionManager.runAfterInteractions(() => {
+ createOrUpdateSubscription(null, roomBatch[key]);
+ });
});
}, WINDOW_TIME);
}
diff --git a/app/views/RoomView/List.js b/app/views/RoomView/List.js
index c39e32e63..864f60cce 100644
--- a/app/views/RoomView/List.js
+++ b/app/views/RoomView/List.js
@@ -25,9 +25,9 @@ class List extends React.Component {
rid: PropTypes.string,
t: PropTypes.string,
tmid: PropTypes.string,
- animated: PropTypes.bool,
theme: PropTypes.string,
- listRef: PropTypes.func
+ listRef: PropTypes.func,
+ navigation: PropTypes.object
};
constructor(props) {
@@ -40,9 +40,17 @@ class List extends React.Component {
loading: true,
end: false,
messages: [],
- refreshing: false
+ refreshing: false,
+ animated: false
};
this.init();
+ this.didFocusListener = props.navigation.addListener('didFocus', () => {
+ if (this.mounted) {
+ this.setState({ animated: true });
+ } else {
+ this.state.animated = true;
+ }
+ });
console.timeEnd(`${ this.constructor.name } init`);
}
@@ -130,6 +138,9 @@ class List extends React.Component {
if (this.onEndReached && this.onEndReached.stop) {
this.onEndReached.stop();
}
+ if (this.didFocusListener && this.didFocusListener.remove) {
+ this.didFocusListener.remove();
+ }
console.countReset(`${ this.constructor.name }.render calls`);
}
@@ -180,7 +191,10 @@ class List extends React.Component {
// eslint-disable-next-line react/sort-comp
update = () => {
- animateNextTransition();
+ const { animated } = this.state;
+ if (animated) {
+ animateNextTransition();
+ }
this.forceUpdate();
};
diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js
index df8b5dffe..2f3150d94 100644
--- a/app/views/RoomView/index.js
+++ b/app/views/RoomView/index.js
@@ -182,8 +182,6 @@ class RoomView extends React.Component {
this.findAndObserveRoom(this.rid);
}
- this.beginAnimating = false;
- this.didFocusListener = props.navigation.addListener('didFocus', () => this.beginAnimating = true);
this.messagebox = React.createRef();
this.list = React.createRef();
this.willBlurListener = props.navigation.addListener('willBlur', () => this.mounted = false);
@@ -289,9 +287,6 @@ class RoomView extends React.Component {
}
}
this.unsubscribe();
- if (this.didFocusListener && this.didFocusListener.remove) {
- this.didFocusListener.remove();
- }
if (this.didMountInteraction && this.didMountInteraction.cancel) {
this.didMountInteraction.cancel();
}
@@ -321,7 +316,6 @@ class RoomView extends React.Component {
navigation.navigate('RoomActionsView', { rid: this.rid, t: this.t, room });
}
- // eslint-disable-next-line react/sort-comp
init = async() => {
try {
this.setState({ loading: true });
@@ -893,7 +887,9 @@ class RoomView extends React.Component {
const {
room, reactionsModalVisible, selectedMessage, loading, reacting
} = this.state;
- const { user, baseUrl, theme } = this.props;
+ const {
+ user, baseUrl, theme, navigation
+ } = this.props;
const { rid, t } = room;
return (
@@ -916,7 +912,7 @@ class RoomView extends React.Component {
room={room}
renderRow={this.renderItem}
loading={loading}
- animated={this.beginAnimating}
+ navigation={navigation}
/>
{this.renderFooter()}
{this.renderActions()}
diff --git a/app/views/RoomsListView/index.js b/app/views/RoomsListView/index.js
index c2a99673f..755b761b6 100644
--- a/app/views/RoomsListView/index.js
+++ b/app/views/RoomsListView/index.js
@@ -182,6 +182,7 @@ class RoomsListView extends React.Component {
console.time(`${ this.constructor.name } mount`);
this.gotSubscriptions = false;
+ this.animated = false;
const { width } = Dimensions.get('window');
this.state = {
searching: false,
@@ -215,9 +216,11 @@ class RoomsListView extends React.Component {
}
});
this.didFocusListener = navigation.addListener('didFocus', () => {
+ this.animated = true;
this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
});
this.willBlurListener = navigation.addListener('willBlur', () => {
+ this.animated = false;
closeServerDropdown();
if (this.backHandler && this.backHandler.remove) {
this.backHandler.remove();
@@ -338,12 +341,11 @@ class RoomsListView extends React.Component {
console.countReset(`${ this.constructor.name }.render calls`);
}
+ // eslint-disable-next-line react/sort-comp
onDimensionsChange = ({ window: { width } }) => this.setState({ width });
- // eslint-disable-next-line react/sort-comp
internalSetState = (...args) => {
- const { navigation } = this.props;
- if (navigation.isFocused()) {
+ if (this.animated) {
animateNextTransition();
}
this.setState(...args);
@@ -532,7 +534,7 @@ class RoomsListView extends React.Component {
prid: item.prid,
room: item
});
- };
+ }
_onPressItem = async(item = {}) => {
if (!item.search) {
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 2a0b1daeb..c0bec2f56 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -34,35 +34,41 @@ PODS:
- React-Core (= 0.61.5)
- React-jsi (= 0.61.5)
- ReactCommon/turbomodule/core (= 0.61.5)
- - Firebase/Core (6.8.1):
+ - Firebase/Core (6.16.0):
- Firebase/CoreOnly
- - FirebaseAnalytics (= 6.1.1)
- - Firebase/CoreOnly (6.8.1):
- - FirebaseCore (= 6.2.3)
- - FirebaseAnalytics (6.1.1):
- - FirebaseCore (~> 6.2)
- - FirebaseInstanceID (~> 4.2)
- - GoogleAppMeasurement (= 6.1.1)
+ - FirebaseAnalytics (= 6.2.2)
+ - Firebase/CoreOnly (6.16.0):
+ - FirebaseCore (= 6.6.1)
+ - FirebaseAnalytics (6.2.2):
+ - FirebaseCore (~> 6.6)
+ - FirebaseInstanceID (~> 4.3)
+ - GoogleAppMeasurement (= 6.2.2)
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
- GoogleUtilities/MethodSwizzler (~> 6.0)
- GoogleUtilities/Network (~> 6.0)
- "GoogleUtilities/NSData+zlib (~> 6.0)"
- - nanopb (~> 0.3)
- - FirebaseCore (6.2.3):
- - FirebaseCoreDiagnostics (~> 1.0)
- - FirebaseCoreDiagnosticsInterop (~> 1.0)
- - GoogleUtilities/Environment (~> 6.2)
- - GoogleUtilities/Logger (~> 6.2)
- - FirebaseCoreDiagnostics (1.0.1):
- - FirebaseCoreDiagnosticsInterop (~> 1.0)
- - GoogleDataTransportCCTSupport (~> 1.0)
- - GoogleUtilities/Environment (~> 6.2)
- - GoogleUtilities/Logger (~> 6.2)
- - FirebaseCoreDiagnosticsInterop (1.0.0)
- - FirebaseInstanceID (4.2.5):
- - FirebaseCore (~> 6.0)
- - GoogleUtilities/Environment (~> 6.0)
- - GoogleUtilities/UserDefaults (~> 6.0)
+ - nanopb (= 0.3.9011)
+ - FirebaseCore (6.6.1):
+ - FirebaseCoreDiagnostics (~> 1.2)
+ - FirebaseCoreDiagnosticsInterop (~> 1.2)
+ - GoogleUtilities/Environment (~> 6.5)
+ - GoogleUtilities/Logger (~> 6.5)
+ - FirebaseCoreDiagnostics (1.2.0):
+ - FirebaseCoreDiagnosticsInterop (~> 1.2)
+ - GoogleDataTransportCCTSupport (~> 1.3)
+ - GoogleUtilities/Environment (~> 6.5)
+ - GoogleUtilities/Logger (~> 6.5)
+ - nanopb (~> 0.3.901)
+ - FirebaseCoreDiagnosticsInterop (1.2.0)
+ - FirebaseInstallations (1.1.0):
+ - FirebaseCore (~> 6.6)
+ - GoogleUtilities/UserDefaults (~> 6.5)
+ - PromisesObjC (~> 1.2)
+ - FirebaseInstanceID (4.3.0):
+ - FirebaseCore (~> 6.6)
+ - FirebaseInstallations (~> 1.0)
+ - GoogleUtilities/Environment (~> 6.5)
+ - GoogleUtilities/UserDefaults (~> 6.5)
- Folly (2018.10.22.00):
- boost-for-react-native
- DoubleConversion
@@ -73,51 +79,52 @@ PODS:
- DoubleConversion
- glog
- glog (0.3.5)
- - GoogleAppMeasurement (6.1.1):
+ - GoogleAppMeasurement (6.2.2):
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
- GoogleUtilities/MethodSwizzler (~> 6.0)
- GoogleUtilities/Network (~> 6.0)
- "GoogleUtilities/NSData+zlib (~> 6.0)"
- - nanopb (~> 0.3)
- - GoogleDataTransport (1.2.0)
- - GoogleDataTransportCCTSupport (1.0.4):
- - GoogleDataTransport (~> 1.2)
- - nanopb
- - GoogleUtilities/AppDelegateSwizzler (6.3.0):
+ - nanopb (= 0.3.9011)
+ - GoogleDataTransport (3.3.1)
+ - GoogleDataTransportCCTSupport (1.3.1):
+ - GoogleDataTransport (~> 3.3)
+ - nanopb (~> 0.3.901)
+ - GoogleUtilities/AppDelegateSwizzler (6.5.1):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- - GoogleUtilities/Environment (6.3.0)
- - GoogleUtilities/Logger (6.3.0):
+ - GoogleUtilities/Environment (6.5.1)
+ - GoogleUtilities/Logger (6.5.1):
- GoogleUtilities/Environment
- - GoogleUtilities/MethodSwizzler (6.3.0):
+ - GoogleUtilities/MethodSwizzler (6.5.1):
- GoogleUtilities/Logger
- - GoogleUtilities/Network (6.3.0):
+ - GoogleUtilities/Network (6.5.1):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- - "GoogleUtilities/NSData+zlib (6.3.0)"
- - GoogleUtilities/Reachability (6.3.0):
+ - "GoogleUtilities/NSData+zlib (6.5.1)"
+ - GoogleUtilities/Reachability (6.5.1):
- GoogleUtilities/Logger
- - GoogleUtilities/UserDefaults (6.3.0):
+ - GoogleUtilities/UserDefaults (6.5.1):
- GoogleUtilities/Logger
- JitsiMeetSDK (2.4.0)
- KeyCommands (2.0.3):
- React
- - libwebp (1.0.3):
- - libwebp/demux (= 1.0.3)
- - libwebp/mux (= 1.0.3)
- - libwebp/webp (= 1.0.3)
- - libwebp/demux (1.0.3):
+ - libwebp (1.1.0):
+ - libwebp/demux (= 1.1.0)
+ - libwebp/mux (= 1.1.0)
+ - libwebp/webp (= 1.1.0)
+ - libwebp/demux (1.1.0):
- libwebp/webp
- - libwebp/mux (1.0.3):
+ - libwebp/mux (1.1.0):
- libwebp/demux
- - libwebp/webp (1.0.3)
- - nanopb (0.3.901):
- - nanopb/decode (= 0.3.901)
- - nanopb/encode (= 0.3.901)
- - nanopb/decode (0.3.901)
- - nanopb/encode (0.3.901)
+ - libwebp/webp (1.1.0)
+ - nanopb (0.3.9011):
+ - nanopb/decode (= 0.3.9011)
+ - nanopb/encode (= 0.3.9011)
+ - nanopb/decode (0.3.9011)
+ - nanopb/encode (0.3.9011)
+ - PromisesObjC (1.2.8)
- RCTRequired (0.61.5)
- RCTTypeSafety (0.61.5):
- FBLazyVector (= 0.61.5)
@@ -395,10 +402,10 @@ PODS:
- RNVectorIcons (6.6.0):
- React
- RSKImageCropper (2.2.3)
- - SDWebImage (5.1.1):
- - SDWebImage/Core (= 5.1.1)
- - SDWebImage/Core (5.1.1)
- - SDWebImageWebPCoder (0.2.4):
+ - SDWebImage (5.5.2):
+ - SDWebImage/Core (= 5.5.2)
+ - SDWebImage/Core (5.5.2)
+ - SDWebImageWebPCoder (0.2.5):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.0)
- UMBarCodeScannerInterface (3.0.0)
@@ -500,7 +507,7 @@ DEPENDENCIES:
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS:
- https://github.com/CocoaPods/Specs.git:
+ trunk:
- boost-for-react-native
- Crashlytics
- Fabric
@@ -509,6 +516,7 @@ SPEC REPOS:
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseCoreDiagnosticsInterop
+ - FirebaseInstallations
- FirebaseInstanceID
- GoogleAppMeasurement
- GoogleDataTransport
@@ -516,6 +524,7 @@ SPEC REPOS:
- GoogleUtilities
- libwebp
- nanopb
+ - PromisesObjC
- RSKImageCropper
- SDWebImage
- SDWebImageWebPCoder
@@ -713,22 +722,24 @@ SPEC CHECKSUMS:
Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74
FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f
FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75
- Firebase: 9cbe4e5b5eaafa05dc932be58b7c8c3820d71e88
- FirebaseAnalytics: 843c7f64a8f9c79f0d03281197ebe7bb1d58d477
- FirebaseCore: e9d9bd1dae61c1e82bc1e0e617a9d832392086a0
- FirebaseCoreDiagnostics: 4c04ae09d0ab027c30179828c6bb47764df1bd13
- FirebaseCoreDiagnosticsInterop: 6829da2b8d1fc795ff1bd99df751d3788035d2cb
- FirebaseInstanceID: 550df9be1f99f751d8fcde3ac342a1e21a0e6c42
+ Firebase: 497158b816d0a86fc31babbd05546fcd7e6083ff
+ FirebaseAnalytics: cf95d3aab897612783020fbd98401d5366f135ee
+ FirebaseCore: 85064903ed6c28e47fec9c7bd149d94ba1b6b6e7
+ FirebaseCoreDiagnostics: 5e78803ab276bc5b50340e3c539c06c3de35c649
+ FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850
+ FirebaseInstallations: 575cd32f2aec0feeb0e44f5d0110a09e5e60b47b
+ FirebaseInstanceID: 6668efc1655a4052c083f287a7141f1ead12f9c2
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
- GoogleAppMeasurement: 86a82f0e1f20b8eedf8e20326530138fd71409de
- GoogleDataTransport: 8f9897b8e073687f24ca8d3c3a8013dec7d2d1cc
- GoogleDataTransportCCTSupport: 7455d07b98851aa63e4c05a34dad356ca588479e
- GoogleUtilities: 9c2c544202301110b29f7974a82e77fdcf12bf51
+ GoogleAppMeasurement: d0560d915abf15e692e8538ba1d58442217b6aff
+ GoogleDataTransport: 0048df6388dab1c254799f2a30365b1dffe20422
+ GoogleDataTransportCCTSupport: f880d70972efa2ed1be4e9173a0f4c5f3dc2d176
+ GoogleUtilities: 06eb53bb579efe7099152735900dd04bf09e7275
JitsiMeetSDK: d4a3aeed1a75fd57e6a78e5d202b6051dfcb9320
KeyCommands: f66c535f698ed14b3d3a4e58859d79a827ea907e
- libwebp: 057912d6d0abfb6357d8bb05c0ea470301f5d61e
- nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
+ libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3
+ nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd
+ PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6
RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1
RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320
React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78
@@ -778,8 +789,8 @@ SPEC CHECKSUMS:
RNUserDefaults: af71a1cdf1c12baf8210bc741c65f5faba9826d6
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4
RSKImageCropper: a446db0e8444a036b34f3c43db01b2373baa4b2a
- SDWebImage: 96d7f03415ccb28d299d765f93557ff8a617abd8
- SDWebImageWebPCoder: cc72085bb20368b2f8dbb21b7e355c667e1309b7
+ SDWebImage: 4d5c027c935438f341ed33dbac53ff9f479922ca
+ SDWebImageWebPCoder: 947093edd1349d820c40afbd9f42acb6cdecd987
UMBarCodeScannerInterface: 84ea2d6b58ff0dc27ef9b68bab71286be18ee020
UMCameraInterface: 26b26005d1756a0d5f4f04f1e168e39ea9154535
UMConstantsInterface: 038bacb19de12b6fd328c589122c8dc977cccf61
diff --git a/ios/Pods/Firebase/CoreOnly/Sources/Firebase.h b/ios/Pods/Firebase/CoreOnly/Sources/Firebase.h
index 5e060e0c1..e5049ca43 100755
--- a/ios/Pods/Firebase/CoreOnly/Sources/Firebase.h
+++ b/ios/Pods/Firebase/CoreOnly/Sources/Firebase.h
@@ -1,3 +1,17 @@
+// Copyright 2019 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
#import
#if !defined(__has_include)
@@ -12,6 +26,10 @@
#import
#endif
+ #if __has_include()
+ #import
+ #endif
+
#if __has_include()
#import
#endif
diff --git a/ios/Pods/GoogleUtilities/LICENSE b/ios/Pods/Firebase/LICENSE
similarity index 100%
rename from ios/Pods/GoogleUtilities/LICENSE
rename to ios/Pods/Firebase/LICENSE
diff --git a/ios/Pods/Firebase/README.md b/ios/Pods/Firebase/README.md
old mode 100755
new mode 100644
index 20aa6928e..5097a89ae
--- a/ios/Pods/Firebase/README.md
+++ b/ios/Pods/Firebase/README.md
@@ -1,93 +1,254 @@
-# Firebase APIs for iOS
+# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk)
-Simplify your iOS development, grow your user base, and monetize more
-effectively with Firebase services.
+This repository contains a subset of the Firebase iOS SDK source. It currently
+includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
+FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
+FirebaseInAppMessagingDisplay, FirebaseMessaging, FirebaseRemoteConfig, and
+FirebaseStorage.
-Much more information can be found at [https://firebase.google.com](https://firebase.google.com).
+The repository also includes GoogleUtilities source. The
+[GoogleUtilities](GoogleUtilities/README.md) pod is
+a set of utilities used by Firebase and other Google products.
-## Install a Firebase SDK using CocoaPods
+Firebase is an app development platform with tools to help you build, grow and
+monetize your app. More information about Firebase can be found at
+[https://firebase.google.com](https://firebase.google.com).
-Firebase distributes several iOS specific APIs and SDKs via CocoaPods.
-You can install the CocoaPods tool on OS X by running the following command from
-the terminal. Detailed information is available in the [Getting Started
-guide](https://guides.cocoapods.org/using/getting-started.html#getting-started).
+## Installation
+See the three subsections for details about three different installation methods.
+1. [Standard pod install](README.md#standard-pod-install)
+1. [Installing from the GitHub repo](README.md#installing-from-github)
+1. [Experimental Carthage](README.md#carthage-ios-only)
+
+### Standard pod install
+
+Go to
+[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup).
+
+### Installing from GitHub
+
+For releases starting with 5.0.0, the source for each release is also deployed
+to CocoaPods master and available via standard
+[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod).
+
+These instructions can be used to access the Firebase repo at other branches,
+tags, or commits.
+
+#### Background
+
+See
+[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod)
+for instructions and options about overriding pod source locations.
+
+#### Accessing Firebase Source Snapshots
+
+All of the official releases are tagged in this repo and available via CocoaPods. To access a local
+source snapshot or unreleased branch, use Podfile directives like the following:
+
+To access FirebaseFirestore via a branch:
```
-$ sudo gem install cocoapods
+pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'
+pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'
```
-## Try out an SDK
-
-You can try any of the SDKs with `pod try`. Run the following command and select
-the SDK you are interested in when prompted:
+To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do:
```
-$ pod try Firebase
+pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk'
+pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk'
```
-Note that some SDKs may require credentials. More information is available in
-the SDK-specific documentation at [https://firebase.google.com/docs/](https://firebase.google.com/docs/).
+### Carthage (iOS only)
-## Add a Firebase SDK to your iOS app
+Instructions for the experimental Carthage distribution are at
+[Carthage](Carthage.md).
-CocoaPods is used to install and manage dependencies in existing Xcode projects.
+### Rome
-1. Create an Xcode project, and save it to your local machine.
-2. Create a file named `Podfile` in your project directory. This file defines
- your project's dependencies, and is commonly referred to as a Podspec.
-3. Open `Podfile`, and add your dependencies. A simple Podspec is shown here:
+Instructions for installing binary frameworks via
+[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md).
- ```
- platform :ios, '8.0'
- pod 'Firebase'
- ```
+## Development
-4. Save the file.
+To develop Firebase software in this repository, ensure that you have at least
+the following software:
-5. Open a terminal and `cd` to the directory containing the Podfile.
+ * Xcode 10.1 (or later)
+ * CocoaPods 1.7.2 (or later)
+ * [CocoaPods generate](https://github.com/square/cocoapods-generate)
- ```
- $ cd /project/
- ```
+For the pod that you want to develop:
-6. Run the `pod install` command. This will install the SDKs specified in the
- Podspec, along with any dependencies they may have.
+`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios`
- ```
- $ pod install
- ```
+Note: If the CocoaPods cache is out of date, you may need to run
+`pod repo update` before the `pod gen` command.
-7. Open your app's `.xcworkspace` file to launch Xcode. Use this file for all
- development on your app.
+Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for
+those platforms. Since 10.2, Xcode does not properly handle multi-platform
+CocoaPods workspaces.
-8. You can also install other Firebase SDKs by adding the subspecs in the
- Podfile.
+Firestore has a self contained Xcode project. See
+[Firestore/README.md](Firestore/README.md).
- ```
- pod 'Firebase/AdMob'
- pod 'Firebase/Analytics'
- pod 'Firebase/Auth'
- pod 'Firebase/Database'
- pod 'Firebase/DynamicLinks'
- pod 'Firebase/Firestore'
- pod 'Firebase/Functions'
- pod 'Firebase/InAppMessaging'
- pod 'Firebase/InAppMessagingDisplay'
- pod 'Firebase/Messaging'
- pod 'Firebase/MLCommon'
- pod 'Firebase/MLModelInterpreter'
- pod 'Firebase/MLNLLanguageID'
- pod 'Firebase/MLNLSmartReply'
- pod 'Firebase/MLNLTranslate'
- pod 'Firebase/MLNaturalLanguage'
- pod 'Firebase/MLVision'
- pod 'Firebase/MLVisionAutoML'
- pod 'Firebase/MLVisionBarcodeModel'
- pod 'Firebase/MLVisionFaceModel'
- pod 'Firebase/MLVisionLabelModel'
- pod 'Firebase/MLVisionObjectDetection'
- pod 'Firebase/MLVisionTextModel'
- pod 'Firebase/Performance'
- pod 'Firebase/RemoteConfig'
- pod 'Firebase/Storage'
- ```
+### Development for Catalyst
+* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`
+* Check the Mac box in the App-iOS Build Settings
+* Sign the App in the Settings Signing & Capabilities tab
+* Click Pods in the Project Manager
+* Add Signing to the iOS host app and unit test targets
+* Select the Unit-unit scheme
+* Run it to build and test
+
+### Adding a New Firebase Pod
+
+See [AddNewPod.md](AddNewPod.md).
+
+### Code Formatting
+
+To ensure that the code is formatted consistently, run the script
+[./scripts/style.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/style.sh)
+before creating a PR.
+
+Travis will verify that any code changes are done in a style compliant way. Install
+`clang-format` and `swiftformat`.
+These commands will get the right versions:
+
+```
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/e3496d9/Formula/clang-format.rb
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/7963c3d/Formula/swiftformat.rb
+```
+
+Note: if you already have a newer version of these installed you may need to
+`brew switch` to this version.
+
+To update this section, find the versions of clang-format and swiftformat.rb to
+match the versions in the CI failure logs
+[here](https://github.com/Homebrew/homebrew-core/tree/master/Formula).
+
+### Running Unit Tests
+
+Select a scheme and press Command-u to build a component and run its unit tests.
+
+#### Viewing Code Coverage
+
+First, make sure that [xcov](https://github.com/nakiostudio/xcov) is installed with `gem install xcov`.
+
+After running the `AllUnitTests_iOS` scheme in Xcode, execute
+`xcov --workspace Firebase.xcworkspace --scheme AllUnitTests_iOS --output_directory xcov_output`
+at Example/ in the terminal. This will aggregate the coverage, and you can run `open xcov_output/index.html` to see the results.
+
+### Running Sample Apps
+In order to run the sample apps and integration tests, you'll need valid
+`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist
+files without real values, but can be replaced with real plist files. To get your own
+`GoogleService-Info.plist` files:
+
+1. Go to the [Firebase Console](https://console.firebase.google.com/)
+2. Create a new Firebase project, if you don't already have one
+3. For each sample app you want to test, create a new Firebase app with the sample app's bundle
+identifier (e.g. `com.google.Database-Example`)
+4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file
+(e.g. in [Example/Database/App/](Example/Database/App/));
+
+Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require
+special Apple capabilities, and you will have to change the sample app to use a unique bundle
+identifier that you can control in your own Apple Developer account.
+
+## Specific Component Instructions
+See the sections below for any special instructions for those components.
+
+### Firebase Auth
+
+If you're doing specific Firebase Auth development, see
+[the Auth Sample README](Example/Auth/README.md) for instructions about
+building and running the FirebaseAuth pod along with various samples and tests.
+
+### Firebase Database
+
+To run the Database Integration tests, make your database authentication rules
+[public](https://firebase.google.com/docs/database/security/quickstart).
+
+### Firebase Storage
+
+To run the Storage Integration tests, follow the instructions in
+[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m).
+
+#### Push Notifications
+
+Push notifications can only be delivered to specially provisioned App IDs in the developer portal.
+In order to actually test receiving push notifications, you will need to:
+
+1. Change the bundle identifier of the sample app to something you own in your Apple Developer
+account, and enable that App ID for push notifications.
+2. You'll also need to
+[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs)
+at **Project Settings > Cloud Messaging > [Your Firebase App]**.
+3. Ensure your iOS device is added to your Apple Developer portal as a test device.
+
+#### iOS Simulator
+
+The iOS Simulator cannot register for remote notifications, and will not receive push notifications.
+In order to receive push notifications, you'll have to follow the steps above and run the app on a
+physical device.
+
+## Community Supported Efforts
+
+We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are
+very grateful! We'd like to empower as many developers as we can to be able to use Firebase and
+participate in the Firebase community.
+
+### tvOS, macOS, and Catalyst
+Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and work on
+tvOS, macOS, and Catalyst.
+
+For tvOS, checkout the [Sample](Example/tvOSSample).
+
+Keep in mind that macOS, Catalyst and tvOS are not officially supported by Firebase, and this
+repository is actively developed primarily for iOS. While we can catch basic unit test issues with
+Travis, there may be some changes where the SDK no longer works as expected on macOS or tvOS. If you
+encounter this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues).
+
+During app setup in the console, you may get to a step that mentions something like "Checking if the app
+has communicated with our servers". This relies on Analytics and will not work on macOS/tvOS/Catalyst.
+**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected.
+
+To install, add a subset of the following to the Podfile:
+
+```
+pod 'Firebase/ABTesting'
+pod 'Firebase/Auth'
+pod 'Firebase/Crashlytics'
+pod 'Firebase/Database'
+pod 'Firebase/Firestore'
+pod 'Firebase/Functions'
+pod 'Firebase/Messaging'
+pod 'Firebase/RemoteConfig'
+pod 'Firebase/Storage'
+```
+
+#### Additional Catalyst Notes
+
+* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`
+to Build Settings.
+* FirebaseFirestore requires signing the
+[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).
+
+## Roadmap
+
+See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source
+plans and directions.
+
+## Contributing
+
+See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase
+iOS SDK.
+
+## License
+
+The contents of this repository is licensed under the
+[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0).
+
+Your use of Firebase is governed by the
+[Terms of Service for Firebase Services](https://firebase.google.com/terms/).
diff --git a/ios/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector b/ios/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector
index 9a0d0f3b3..1a7eaec7d 100755
Binary files a/ios/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector and b/ios/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector differ
diff --git a/ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics b/ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics
index 7c4c6e164..fa7ceb951 100755
Binary files a/ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics and b/ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics differ
diff --git a/ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h b/ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h
index afb9f820b..be0b1faee 100755
--- a/ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h
+++ b/ios/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h
@@ -9,6 +9,10 @@ NS_ASSUME_NONNULL_BEGIN
/// The top level Firebase Analytics singleton that provides methods for logging events and setting
/// user properties. See the developer guides for general
/// information on using Firebase Analytics in your apps.
+///
+/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling
+/// certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in
+/// unexpected crashes at runtime.
NS_SWIFT_NAME(Analytics)
@interface FIRAnalytics : NSObject
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.m
similarity index 97%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.m
index a57936b9b..3a7d6de0e 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.m
@@ -14,7 +14,7 @@
#import
-#import "Private/FIRAnalyticsConfiguration.h"
+#import "FirebaseCore/Sources/Private/FIRAnalyticsConfiguration.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRApp.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRApp.m
similarity index 88%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRApp.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRApp.m
index 48b76f60e..02f3ac3f8 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRApp.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRApp.m
@@ -22,17 +22,22 @@
#import
#endif
-#import "FIRApp.h"
+#import
-#import "Private/FIRAnalyticsConfiguration.h"
-#import "Private/FIRAppInternal.h"
-#import "Private/FIRBundleUtil.h"
-#import "Private/FIRComponentContainerInternal.h"
-#import "Private/FIRConfigurationInternal.h"
-#import "Private/FIRCoreDiagnosticsConnector.h"
-#import "Private/FIRLibrary.h"
-#import "Private/FIRLogger.h"
-#import "Private/FIROptionsInternal.h"
+#import "FirebaseCore/Sources/FIRBundleUtil.h"
+#import "FirebaseCore/Sources/FIRVersion.h"
+#import "FirebaseCore/Sources/Private/FIRAnalyticsConfiguration.h"
+#import "FirebaseCore/Sources/Private/FIRAppInternal.h"
+#import "FirebaseCore/Sources/Private/FIRComponentContainerInternal.h"
+#import "FirebaseCore/Sources/Private/FIRConfigurationInternal.h"
+#import "FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h"
+#import "FirebaseCore/Sources/Private/FIRLibrary.h"
+#import "FirebaseCore/Sources/Private/FIRLogger.h"
+#import "FirebaseCore/Sources/Private/FIROptionsInternal.h"
+
+#import
+
+#import
// The kFIRService strings are only here while transitioning CoreDiagnostics from the Analytics
// pod to a Core dependency. These symbols are not used and should be deleted after the transition.
@@ -111,6 +116,7 @@ static NSMutableArray> *sRegisteredAsConfigurable;
static NSMutableDictionary *sAllApps;
static FIRApp *sDefaultApp;
static NSMutableDictionary *sLibraryVersions;
+static dispatch_once_t sFirebaseUserAgentOnceToken;
+ (void)configure {
FIROptions *options = [FIROptions defaultOptions];
@@ -159,8 +165,9 @@ static NSMutableDictionary *sLibraryVersions;
if ([name isEqualToString:kFIRDefaultAppName]) {
if (sDefaultApp) {
- [NSException raise:kFirebaseCoreErrorDomain
- format:@"Default app has already been configured."];
+ // The default app already exixts. Handle duplicate `configure` calls and return.
+ [self appWasConfiguredTwice:sDefaultApp usingOptions:options];
+ return;
}
FIRLogDebug(kFIRLoggerCore, @"I-COR000001", @"Configuring the default app.");
@@ -176,8 +183,9 @@ static NSMutableDictionary *sLibraryVersions;
@synchronized(self) {
if (sAllApps && sAllApps[name]) {
- [NSException raise:kFirebaseCoreErrorDomain
- format:@"App named %@ has already been configured.", name];
+ // The app already exists. Handle a duplicate `configure` call and return.
+ [self appWasConfiguredTwice:sAllApps[name] usingOptions:options];
+ return;
}
}
@@ -191,10 +199,44 @@ static NSMutableDictionary *sLibraryVersions;
}
[FIRApp addAppToAppDictionary:app];
+
+ // The FIRApp instance is ready to go, `sDefaultApp` is assigned, other SDKs are now ready to be
+ // instantiated.
+ [app.container instantiateEagerComponents];
[FIRApp sendNotificationsToSDKs:app];
}
}
+/// Called when `configure` has been called multiple times for the same app. This can either throw
+/// an exception (most cases) or ignore the duplicate configuration in situations where it's allowed
+/// like an extension.
++ (void)appWasConfiguredTwice:(FIRApp *)app usingOptions:(FIROptions *)options {
+ // Only extensions should potentially be able to call `configure` more than once.
+ if (![GULAppEnvironmentUtil isAppExtension]) {
+ // Throw an exception since this is now an invalid state.
+ if (app.isDefaultApp) {
+ [NSException raise:kFirebaseCoreErrorDomain
+ format:@"Default app has already been configured."];
+ } else {
+ [NSException raise:kFirebaseCoreErrorDomain
+ format:@"App named %@ has already been configured.", app.name];
+ }
+ }
+
+ // In an extension, the entry point could be called multiple times. As long as the options are
+ // identical we should allow multiple `configure` calls.
+ if ([options isEqual:app.options]) {
+ // Everything is identical but the extension's lifecycle triggered `configure` twice.
+ // Ignore duplicate calls and return since everything should still be in a valid state.
+ FIRLogDebug(kFIRLoggerCore, @"I-COR000035",
+ @"Ignoring second `configure` call in an extension.");
+ return;
+ } else {
+ [NSException raise:kFirebaseCoreErrorDomain
+ format:@"App named %@ has already been configured.", app.name];
+ }
+}
+
+ (FIRApp *)defaultApp {
if (sDefaultApp) {
return sDefaultApp;
@@ -236,6 +278,7 @@ static NSMutableDictionary *sLibraryVersions;
sAllApps = nil;
[sLibraryVersions removeAllObjects];
sLibraryVersions = nil;
+ sFirebaseUserAgentOnceToken = 0;
}
}
@@ -352,7 +395,7 @@ static NSMutableDictionary *sLibraryVersions;
}
// Check if the Analytics flag is explicitly set. If so, no further actions are necessary.
- if ([self.options isAnalyticsCollectionExpicitlySet]) {
+ if ([self.options isAnalyticsCollectionExplicitlySet]) {
return;
}
@@ -517,6 +560,25 @@ static NSMutableDictionary *sLibraryVersions;
+ (NSString *)firebaseUserAgent {
@synchronized(self) {
+ dispatch_once(&sFirebaseUserAgentOnceToken, ^{
+ // Report FirebaseCore version for useragent string
+ [FIRApp registerLibrary:@"fire-ios"
+ withVersion:[NSString stringWithUTF8String:FIRCoreVersionString]];
+
+ NSDictionary *info = [[NSBundle mainBundle] infoDictionary];
+ NSString *xcodeVersion = info[@"DTXcodeBuild"];
+ NSString *sdkVersion = info[@"DTSDKBuild"];
+ if (xcodeVersion) {
+ [FIRApp registerLibrary:@"xcode" withVersion:xcodeVersion];
+ }
+ if (sdkVersion) {
+ [FIRApp registerLibrary:@"apple-sdk" withVersion:sdkVersion];
+ }
+
+ NSString *swiftFlagValue = [self hasSwiftRuntime] ? @"true" : @"false";
+ [FIRApp registerLibrary:@"swift" withVersion:swiftFlagValue];
+ });
+
NSMutableArray *libraries =
[[NSMutableArray alloc] initWithCapacity:sLibraryVersions.count];
for (NSString *libraryName in sLibraryVersions) {
@@ -528,6 +590,20 @@ static NSMutableDictionary *sLibraryVersions;
}
}
++ (BOOL)hasSwiftRuntime {
+ // The class
+ // [Swift._SwiftObject](https://github.com/apple/swift/blob/5eac3e2818eb340b11232aff83edfbd1c307fa03/stdlib/public/runtime/SwiftObject.h#L35)
+ // is a part of Swift runtime, so it should be present if Swift runtime is available.
+
+ BOOL hasSwiftRuntime =
+ objc_lookUpClass("Swift._SwiftObject") != nil ||
+ // Swift object class name before
+ // https://github.com/apple/swift/commit/9637b4a6e11ddca72f5f6dbe528efc7c92f14d01
+ objc_getClass("_TtCs12_SwiftObject") != nil;
+
+ return hasSwiftRuntime;
+}
+
- (void)checkExpectedBundleID {
NSArray *bundles = [FIRBundleUtil relevantBundles];
NSString *expectedBundleID = [self expectedBundleID];
@@ -811,16 +887,16 @@ static NSMutableDictionary *sLibraryVersions;
- (void)subscribeForAppDidBecomeActiveNotifications {
#if TARGET_OS_IOS || TARGET_OS_TV
NSNotificationName notificationName = UIApplicationDidBecomeActiveNotification;
-#endif
-
-#if TARGET_OS_OSX
+#elif TARGET_OS_OSX
NSNotificationName notificationName = NSApplicationDidBecomeActiveNotification;
#endif
+#if !TARGET_OS_WATCH
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appDidBecomeActive:)
name:notificationName
object:nil];
+#endif
}
- (void)appDidBecomeActive:(NSNotification *)notification {
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRAppAssociationRegistration.m
similarity index 96%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRAppAssociationRegistration.m
index 2aecdabe1..e4125cd25 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRAppAssociationRegistration.m
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#import "Private/FIRAppAssociationRegistration.h"
+#import "FirebaseCore/Sources/Private/FIRAppAssociationRegistration.h"
#import
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRBundleUtil.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRBundleUtil.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRBundleUtil.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.m
similarity index 98%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRBundleUtil.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.m
index 65fc309f1..b858f14c4 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRBundleUtil.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.m
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#import "Private/FIRBundleUtil.h"
+#import "FirebaseCore/Sources/FIRBundleUtil.h"
#import
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRComponent.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponent.m
similarity index 93%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRComponent.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponent.m
index 2474d1aab..9c1fbed3c 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRComponent.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponent.m
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#import "Private/FIRComponent.h"
+#import "FirebaseCore/Sources/Private/FIRComponent.h"
-#import "Private/FIRComponentContainer.h"
-#import "Private/FIRDependency.h"
+#import "FirebaseCore/Sources/Private/FIRComponentContainer.h"
+#import "FirebaseCore/Sources/Private/FIRDependency.h"
@interface FIRComponent ()
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRComponentContainer.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainer.m
similarity index 67%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRComponentContainer.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainer.m
index 0306da55b..9f91786fe 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRComponentContainer.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainer.m
@@ -14,26 +14,27 @@
* limitations under the License.
*/
-#import "Private/FIRComponentContainer.h"
+#import "FirebaseCore/Sources/Private/FIRComponentContainer.h"
-#import "Private/FIRAppInternal.h"
-#import "Private/FIRComponent.h"
-#import "Private/FIRLibrary.h"
-#import "Private/FIRLogger.h"
+#import "FirebaseCore/Sources/Private/FIRAppInternal.h"
+#import "FirebaseCore/Sources/Private/FIRComponent.h"
+#import "FirebaseCore/Sources/Private/FIRLibrary.h"
+#import "FirebaseCore/Sources/Private/FIRLogger.h"
NS_ASSUME_NONNULL_BEGIN
-@interface FIRComponentContainer () {
- dispatch_queue_t _containerQueue;
-}
+@interface FIRComponentContainer ()
-/// The dictionary of components that are registered for a particular app. The key is an NSString
+/// The dictionary of components that are registered for a particular app. The key is an `NSString`
/// of the protocol.
@property(nonatomic, strong) NSMutableDictionary *components;
/// Cached instances of components that requested to be cached.
@property(nonatomic, strong) NSMutableDictionary *cachedInstances;
+/// Protocols of components that have requested to be eagerly instantiated.
+@property(nonatomic, strong, nullable) NSMutableArray *eagerProtocolsToInstantiate;
+
@end
@implementation FIRComponentContainer
@@ -69,8 +70,6 @@ static NSMutableSet *sFIRComponentRegistrants;
_app = app;
_cachedInstances = [NSMutableDictionary dictionary];
_components = [NSMutableDictionary dictionary];
- _containerQueue =
- dispatch_queue_create("com.google.FirebaseComponentContainer", DISPATCH_QUEUE_SERIAL);
[self populateComponentsFromRegisteredClasses:allRegistrants forApp:app];
}
@@ -78,6 +77,9 @@ static NSMutableSet *sFIRComponentRegistrants;
}
- (void)populateComponentsFromRegisteredClasses:(NSSet *)classes forApp:(FIRApp *)app {
+ // Keep track of any components that need to eagerly instantiate after all components are added.
+ self.eagerProtocolsToInstantiate = [[NSMutableArray alloc] init];
+
// Loop through the verified component registrants and populate the components array.
for (Class klass in classes) {
// Loop through all the components being registered and store them as appropriate.
@@ -96,14 +98,16 @@ static NSMutableSet *sFIRComponentRegistrants;
// Store the creation block for later usage.
self.components[protocolName] = component.creationBlock;
- // Instantiate the instance if it has requested to be instantiated.
+ // Queue any protocols that should be eagerly instantiated. Don't instantiate them yet
+ // because they could depend on other components that haven't been added to the components
+ // array yet.
BOOL shouldInstantiateEager =
(component.instantiationTiming == FIRInstantiationTimingAlwaysEager);
BOOL shouldInstantiateDefaultEager =
(component.instantiationTiming == FIRInstantiationTimingEagerInDefaultApp &&
[app isDefaultApp]);
if (shouldInstantiateEager || shouldInstantiateDefaultEager) {
- [self instantiateInstanceForProtocol:component.protocol withBlock:component.creationBlock];
+ [self.eagerProtocolsToInstantiate addObject:component.protocol];
}
}
}
@@ -111,11 +115,28 @@ static NSMutableSet *sFIRComponentRegistrants;
#pragma mark - Instance Creation
+- (void)instantiateEagerComponents {
+ // After all components are registered, instantiate the ones that are requesting eager
+ // instantiation.
+ @synchronized(self) {
+ for (Protocol *protocol in self.eagerProtocolsToInstantiate) {
+ // Get an instance for the protocol, which will instantiate it since it couldn't have been
+ // cached yet. Ignore the instance coming back since we don't need it.
+ __unused id unusedInstance = [self instanceForProtocol:protocol];
+ }
+
+ // All eager instantiation is complete, clear the stored property now.
+ self.eagerProtocolsToInstantiate = nil;
+ }
+}
+
/// Instantiate an instance of a class that conforms to the specified protocol.
/// This will:
/// - Call the block to create an instance if possible,
/// - Validate that the instance returned conforms to the protocol it claims to,
/// - Cache the instance if the block requests it
+///
+/// Note that this method assumes the caller already has @sychronized on self.
- (nullable id)instantiateInstanceForProtocol:(Protocol *)protocol
withBlock:(FIRComponentCreationBlock)creationBlock {
if (!creationBlock) {
@@ -140,9 +161,7 @@ static NSMutableSet *sFIRComponentRegistrants;
// The instance is ready to be returned, but check if it should be cached first before returning.
if (shouldCache) {
- dispatch_sync(_containerQueue, ^{
- self.cachedInstances[protocolName] = instance;
- });
+ self.cachedInstances[protocolName] = instance;
}
return instance;
@@ -153,47 +172,35 @@ static NSMutableSet *sFIRComponentRegistrants;
- (nullable id)instanceForProtocol:(Protocol *)protocol {
// Check if there is a cached instance, and return it if so.
NSString *protocolName = NSStringFromProtocol(protocol);
- __block id cachedInstance;
- dispatch_sync(_containerQueue, ^{
+
+ id cachedInstance;
+ @synchronized(self) {
cachedInstance = self.cachedInstances[protocolName];
- });
-
- if (cachedInstance) {
- return cachedInstance;
+ if (!cachedInstance) {
+ // Use the creation block to instantiate an instance and return it.
+ FIRComponentCreationBlock creationBlock = self.components[protocolName];
+ cachedInstance = [self instantiateInstanceForProtocol:protocol withBlock:creationBlock];
+ }
}
-
- // Use the creation block to instantiate an instance and return it.
- FIRComponentCreationBlock creationBlock = self.components[protocolName];
- return [self instantiateInstanceForProtocol:protocol withBlock:creationBlock];
+ return cachedInstance;
}
#pragma mark - Lifecycle
- (void)removeAllCachedInstances {
- // Loop through the cache and notify each instance that is a maintainer to clean up after itself.
- // Design note: we're getting a copy here, unlocking the cached instances, iterating over the
- // copy, then locking and removing all cached instances. A race condition *could* exist where a
- // new cached instance is created between the copy and the removal, but the chances are slim and
- // side-effects are significantly smaller than including the entire loop in the `dispatch_sync`
- // block (access to the cache from inside the block would deadlock and crash).
- __block NSDictionary *instancesCopy;
- dispatch_sync(_containerQueue, ^{
- instancesCopy = [self.cachedInstances copy];
- });
-
- for (id instance in instancesCopy.allValues) {
- if ([instance conformsToProtocol:@protocol(FIRComponentLifecycleMaintainer)] &&
- [instance respondsToSelector:@selector(appWillBeDeleted:)]) {
- [instance appWillBeDeleted:self.app];
+ @synchronized(self) {
+ // Loop through the cache and notify each instance that is a maintainer to clean up after
+ // itself.
+ for (id instance in self.cachedInstances.allValues) {
+ if ([instance conformsToProtocol:@protocol(FIRComponentLifecycleMaintainer)] &&
+ [instance respondsToSelector:@selector(appWillBeDeleted:)]) {
+ [instance appWillBeDeleted:self.app];
+ }
}
- }
- instancesCopy = nil;
-
- // Empty the cache.
- dispatch_sync(_containerQueue, ^{
+ // Empty the cache.
[self.cachedInstances removeAllObjects];
- });
+ }
}
@end
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRComponentType.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentType.m
similarity index 86%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRComponentType.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentType.m
index bdc004fbc..6410f2ea1 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRComponentType.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentType.m
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#import "Private/FIRComponentType.h"
+#import "FirebaseCore/Sources/Private/FIRComponentType.h"
-#import "Private/FIRComponentContainerInternal.h"
+#import "FirebaseCore/Sources/Private/FIRComponentContainerInternal.h"
@implementation FIRComponentType
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRConfiguration.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfiguration.m
similarity index 90%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRConfiguration.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfiguration.m
index 869f73d7f..a1c9f4a2e 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRConfiguration.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfiguration.m
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#import "Private/FIRConfigurationInternal.h"
+#import "FirebaseCore/Sources/Private/FIRConfigurationInternal.h"
-#import "Private/FIRAnalyticsConfiguration.h"
+#import "FirebaseCore/Sources/Private/FIRAnalyticsConfiguration.h"
extern void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel);
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRCoreDiagnosticsConnector.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRCoreDiagnosticsConnector.m
similarity index 90%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRCoreDiagnosticsConnector.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRCoreDiagnosticsConnector.m
index 7d504e86b..4981ca1b0 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRCoreDiagnosticsConnector.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRCoreDiagnosticsConnector.m
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-#import "Private/FIRCoreDiagnosticsConnector.h"
+#import "FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h"
#import
#import
-#import "Private/FIRAppInternal.h"
-#import "Private/FIRDiagnosticsData.h"
-#import "Private/FIROptionsInternal.h"
+#import "FirebaseCore/Sources/Private/FIRAppInternal.h"
+#import "FirebaseCore/Sources/Private/FIRDiagnosticsData.h"
+#import "FirebaseCore/Sources/Private/FIROptionsInternal.h"
// Define the interop class symbol declared as an extern in FIRCoreDiagnosticsInterop.
Class FIRCoreDiagnosticsImplementation;
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRDependency.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRDependency.m
similarity index 95%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRDependency.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRDependency.m
index f97998414..e1e25783e 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRDependency.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRDependency.m
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#import "Private/FIRDependency.h"
+#import "FirebaseCore/Sources/Private/FIRDependency.h"
@interface FIRDependency ()
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRDiagnosticsData.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRDiagnosticsData.m
similarity index 91%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRDiagnosticsData.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRDiagnosticsData.m
index 04769737f..bbe0561d9 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRDiagnosticsData.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRDiagnosticsData.m
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#import "Private/FIRDiagnosticsData.h"
+#import "FirebaseCore/Sources/Private/FIRDiagnosticsData.h"
#import
-#import "Private/FIRAppInternal.h"
-#import "Private/FIROptionsInternal.h"
+#import "FirebaseCore/Sources/Private/FIRAppInternal.h"
+#import "FirebaseCore/Sources/Private/FIROptionsInternal.h"
@implementation FIRDiagnosticsData {
/** Backing ivar for the diagnosticObjects property. */
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRErrors.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRErrors.m
similarity index 94%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRErrors.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRErrors.m
index 72120c5c9..104eeb825 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRErrors.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRErrors.m
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#import "Private/FIRErrors.h"
+#import "FirebaseCore/Sources/Private/FIRErrors.h"
NSString *const kFirebaseErrorDomain = @"com.firebase";
NSString *const kFirebaseConfigErrorDomain = @"com.firebase.config";
diff --git a/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRHeartbeatInfo.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRHeartbeatInfo.m
new file mode 100644
index 000000000..f1359f5d6
--- /dev/null
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRHeartbeatInfo.m
@@ -0,0 +1,61 @@
+// Copyright 2019 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import "FirebaseCore/Sources/Private/FIRHeartbeatInfo.h"
+#import
+#import
+
+const static long secondsInDay = 864000;
+@implementation FIRHeartbeatInfo : NSObject
+
+/** Updates the storage with the heartbeat information corresponding to this tag.
+ * @param heartbeatTag Tag which could either be sdk specific tag or the global tag.
+ * @return Boolean representing whether the heartbeat needs to be sent for this tag or not.
+ */
++ (BOOL)updateIfNeededHeartbeatDateForTag:(NSString *)heartbeatTag {
+ @synchronized(self) {
+ NSString *const kHeartbeatStorageFile = @"HEARTBEAT_INFO_STORAGE";
+ GULHeartbeatDateStorage *dataStorage =
+ [[GULHeartbeatDateStorage alloc] initWithFileName:kHeartbeatStorageFile];
+ NSDate *heartbeatTime = [dataStorage heartbeatDateForTag:heartbeatTag];
+ NSDate *currentDate = [NSDate date];
+ if (heartbeatTime != nil) {
+ NSTimeInterval secondsBetween = [currentDate timeIntervalSinceDate:heartbeatTime];
+ if (secondsBetween < secondsInDay) {
+ return false;
+ }
+ }
+ return [dataStorage setHearbeatDate:currentDate forTag:heartbeatTag];
+ }
+}
+
++ (FIRHeartbeatInfoCode)heartbeatCodeForTag:(NSString *)heartbeatTag {
+ NSString *globalTag = @"GLOBAL";
+ BOOL isSdkHeartbeatNeeded = [FIRHeartbeatInfo updateIfNeededHeartbeatDateForTag:heartbeatTag];
+ BOOL isGlobalHeartbeatNeeded = [FIRHeartbeatInfo updateIfNeededHeartbeatDateForTag:globalTag];
+ if (!isSdkHeartbeatNeeded && !isGlobalHeartbeatNeeded) {
+ // Both sdk and global heartbeat not needed.
+ return FIRHeartbeatInfoCodeNone;
+ } else if (isSdkHeartbeatNeeded && !isGlobalHeartbeatNeeded) {
+ // Only SDK heartbeat needed.
+ return FIRHeartbeatInfoCodeSDK;
+ } else if (!isSdkHeartbeatNeeded && isGlobalHeartbeatNeeded) {
+ // Only global heartbeat needed.
+ return FIRHeartbeatInfoCodeGlobal;
+ } else {
+ // Both sdk and global heartbeat are needed.
+ return FIRHeartbeatInfoCodeCombined;
+ }
+}
+@end
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRLogger.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRLogger.m
similarity index 98%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRLogger.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRLogger.m
index 532a96c29..ba2ee1f58 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIRLogger.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRLogger.m
@@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#import "Private/FIRLogger.h"
+#import "FirebaseCore/Sources/Private/FIRLogger.h"
#import
#import
#import
-#import "Private/FIRVersion.h"
+#import "FirebaseCore/Sources/FIRVersion.h"
FIRLoggerService kFIRLoggerCore = @"[Firebase/Core]";
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIROptions.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIROptions.m
similarity index 86%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIROptions.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIROptions.m
index 89a679a74..d18533094 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/FIROptions.m
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIROptions.m
@@ -12,12 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#import "Private/FIRAppInternal.h"
-#import "Private/FIRBundleUtil.h"
-#import "Private/FIRErrors.h"
-#import "Private/FIRLogger.h"
-#import "Private/FIROptionsInternal.h"
-#import "Private/FIRVersion.h"
+#import "FirebaseCore/Sources/FIRBundleUtil.h"
+#import "FirebaseCore/Sources/FIRVersion.h"
+#import "FirebaseCore/Sources/Private/FIRAppInternal.h"
+#import "FirebaseCore/Sources/Private/FIRLogger.h"
+#import "FirebaseCore/Sources/Private/FIROptionsInternal.h"
// Keys for the strings in the plist file.
NSString *const kFIRAPIKey = @"API_KEY";
@@ -110,22 +109,6 @@ static NSDictionary *sDefaultOptionsDictionary = nil;
#pragma mark - Private class methods
-+ (void)initialize {
- // Report FirebaseCore version for useragent string
- [FIRApp registerLibrary:@"fire-ios"
- withVersion:[NSString stringWithUTF8String:FIRCoreVersionString]];
-
- NSDictionary *info = [[NSBundle mainBundle] infoDictionary];
- NSString *xcodeVersion = info[@"DTXcodeBuild"];
- NSString *sdkVersion = info[@"DTSDKBuild"];
- if (xcodeVersion) {
- [FIRApp registerLibrary:@"xcode" withVersion:xcodeVersion];
- }
- if (sdkVersion) {
- [FIRApp registerLibrary:@"apple-sdk" withVersion:sdkVersion];
- }
-}
-
+ (NSDictionary *)defaultOptionsDictionary {
if (sDefaultOptionsDictionary != nil) {
return sDefaultOptionsDictionary;
@@ -346,6 +329,59 @@ static NSDictionary *sDefaultOptionsDictionary = nil;
_appGroupID = [appGroupID copy];
}
+#pragma mark - Equality
+
+- (BOOL)isEqual:(id)object {
+ if (!object || ![object isKindOfClass:[FIROptions class]]) {
+ return NO;
+ }
+
+ return [self isEqualToOptions:(FIROptions *)object];
+}
+
+- (BOOL)isEqualToOptions:(FIROptions *)options {
+ // Skip any non-FIROptions classes.
+ if (![options isKindOfClass:[FIROptions class]]) {
+ return NO;
+ }
+
+ // Check the internal dictionary and custom properties for differences.
+ if (![options.optionsDictionary isEqualToDictionary:self.optionsDictionary]) {
+ return NO;
+ }
+
+ // Validate extra properties not contained in the dictionary. Only validate it if one of the
+ // objects has the property set.
+ if ((options.deepLinkURLScheme != nil || self.deepLinkURLScheme != nil) &&
+ ![options.deepLinkURLScheme isEqualToString:self.deepLinkURLScheme]) {
+ return NO;
+ }
+
+ if ((options.appGroupID != nil || self.appGroupID != nil) &&
+ ![options.appGroupID isEqualToString:self.appGroupID]) {
+ return NO;
+ }
+
+ // Validate the Analytics options haven't changed with the Info.plist.
+ if (![options.analyticsOptionsDictionary isEqualToDictionary:self.analyticsOptionsDictionary]) {
+ return NO;
+ }
+
+ // We don't care about the `editingLocked` or `usingOptionsFromDefaultPlist` properties since
+ // those relate to lifecycle and construction, we only care if the contents of the options
+ // themselves are equal.
+ return YES;
+}
+
+- (NSUInteger)hash {
+ // This is strongly recommended for any object that implements a custom `isEqual:` method to
+ // ensure that dictionary and set behavior matches other `isEqual:` checks.
+ // Note: `self.analyticsOptionsDictionary` was left out here since it solely relies on the
+ // contents of the main bundle's `Info.plist`. We should avoid reading that file and the contents
+ // should be identical.
+ return self.optionsDictionary.hash ^ self.deepLinkURLScheme.hash ^ self.appGroupID.hash;
+}
+
#pragma mark - Internal instance methods
- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary {
@@ -399,7 +435,7 @@ static NSDictionary *sDefaultOptionsDictionary = nil;
return [value boolValue];
}
-- (BOOL)isAnalyticsCollectionExpicitlySet {
+- (BOOL)isAnalyticsCollectionExplicitlySet {
// If it's de-activated, it classifies as explicity set. If not, it's not a good enough indication
// that the developer wants FirebaseAnalytics enabled so continue checking.
if (self.isAnalyticsCollectionDeactivated) {
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRVersion.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRVersion.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRVersion.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRVersion.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/FIRVersion.m b/ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRVersion.m
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/FIRVersion.m
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/FIRVersion.m
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRAnalyticsConfiguration.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRAnalyticsConfiguration.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRAnalyticsConfiguration.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRAnalyticsConfiguration.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRAppAssociationRegistration.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRAppAssociationRegistration.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRAppAssociationRegistration.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRAppAssociationRegistration.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRAppInternal.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRAppInternal.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRAppInternal.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRAppInternal.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponent.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponent.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponent.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponent.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentContainer.h
similarity index 95%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentContainer.h
index f3dc356d6..8dfab9c10 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentContainer.h
@@ -15,8 +15,8 @@
*/
#import
-#import "FIRComponentType.h"
-#import "FIRLibrary.h"
+#import
+#import
NS_ASSUME_NONNULL_BEGIN
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentContainerInternal.h
similarity index 76%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentContainerInternal.h
index e8552fa25..2b7798189 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentContainerInternal.h
@@ -15,8 +15,8 @@
*/
#import
-#import "FIRComponent.h"
-#import "FIRComponentContainer.h"
+#import
+#import
@class FIRApp;
@@ -24,13 +24,16 @@ NS_ASSUME_NONNULL_BEGIN
@interface FIRComponentContainer (Private)
-/// Initializes a contain for a given app. This should only be called by the app itself.
+/// Initializes a container for a given app. This should only be called by the app itself.
- (instancetype)initWithApp:(FIRApp *)app;
/// Retrieves an instance that conforms to the specified protocol. This will return `nil` if the
-/// protocol wasn't registered, or if the instance couldn't instantiate for the provided app.
+/// protocol wasn't registered, or if the instance couldn't be instantiated for the provided app.
- (nullable id)instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:));
+/// Instantiates all the components that have registered as "eager" after initialization.
+- (void)instantiateEagerComponents;
+
/// Remove all of the cached instances stored and allow them to clean up after themselves.
- (void)removeAllCachedInstances;
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentType.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentType.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentType.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRComponentType.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRConfigurationInternal.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRConfigurationInternal.h
similarity index 95%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRConfigurationInternal.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRConfigurationInternal.h
index ee1688670..0d1a36f66 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRConfigurationInternal.h
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRConfigurationInternal.h
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#import "FIRConfiguration.h"
+#import
@class FIRAnalyticsConfiguration;
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRCoreDiagnosticsConnector.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRCoreDiagnosticsConnector.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRDependency.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRDependency.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRDependency.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRDependency.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRDiagnosticsData.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRDiagnosticsData.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRDiagnosticsData.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRDiagnosticsData.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRErrorCode.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRErrorCode.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRErrorCode.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRErrorCode.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRErrors.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRErrors.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRErrors.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRErrors.h
diff --git a/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h
new file mode 100644
index 000000000..bfff73e5d
--- /dev/null
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRHeartbeatInfo.h
@@ -0,0 +1,39 @@
+// Copyright 2019 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FIRHeartbeatInfo : NSObject
+
+// Enum representing the different heartbeat codes.
+typedef NS_ENUM(NSInteger, FIRHeartbeatInfoCode) {
+ FIRHeartbeatInfoCodeNone = 0,
+ FIRHeartbeatInfoCodeSDK = 1,
+ FIRHeartbeatInfoCodeGlobal = 2,
+ FIRHeartbeatInfoCodeCombined = 3,
+};
+
+/**
+ * Get heartbeat code requred for the sdk.
+ * @param heartbeatTag String representing the sdk heartbeat tag.
+ * @return Heartbeat code indicating whether or not an sdk/global heartbeat
+ * needs to be sent
+ */
++ (FIRHeartbeatInfoCode)heartbeatCodeForTag:(NSString *)heartbeatTag;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRLibrary.h
similarity index 97%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRLibrary.h
index 728c06232..af9d9685d 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRLibrary.h
@@ -18,7 +18,8 @@
#define FIRLibrary_h
#import
-#import "FIRComponent.h"
+
+#import
@class FIRApp;
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIRLogger.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRLogger.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIRLogger.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIRLogger.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIROptionsInternal.h
similarity index 97%
rename from ios/Pods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIROptionsInternal.h
index 117efdaa0..0660a3cd8 100644
--- a/ios/Pods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h
+++ b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Private/FIROptionsInternal.h
@@ -65,7 +65,7 @@ extern NSString *const kServiceInfoFileType;
* Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at
* runtime.
*/
-@property(nonatomic, readonly) BOOL isAnalyticsCollectionExpicitlySet;
+@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet;
/**
* Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Public/FIRApp.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FIRApp.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Public/FIRApp.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FIRApp.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Public/FIRConfiguration.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FIRConfiguration.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Public/FIRConfiguration.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FIRConfiguration.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Public/FIRLoggerLevel.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FIRLoggerLevel.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Public/FIRLoggerLevel.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FIRLoggerLevel.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Public/FIROptions.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FIROptions.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Public/FIROptions.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FIROptions.h
diff --git a/ios/Pods/FirebaseCore/Firebase/Core/Public/FirebaseCore.h b/ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore.h
similarity index 100%
rename from ios/Pods/FirebaseCore/Firebase/Core/Public/FirebaseCore.h
rename to ios/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore.h
diff --git a/ios/Pods/FirebaseCore/README.md b/ios/Pods/FirebaseCore/README.md
index d75ae8cb1..5097a89ae 100644
--- a/ios/Pods/FirebaseCore/README.md
+++ b/ios/Pods/FirebaseCore/README.md
@@ -3,7 +3,8 @@
This repository contains a subset of the Firebase iOS SDK source. It currently
includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
-FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage.
+FirebaseInAppMessagingDisplay, FirebaseMessaging, FirebaseRemoteConfig, and
+FirebaseStorage.
The repository also includes GoogleUtilities source. The
[GoogleUtilities](GoogleUtilities/README.md) pod is
@@ -75,14 +76,31 @@ the following software:
* Xcode 10.1 (or later)
* CocoaPods 1.7.2 (or later)
+ * [CocoaPods generate](https://github.com/square/cocoapods-generate)
For the pod that you want to develop:
-`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open`
+`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios`
+
+Note: If the CocoaPods cache is out of date, you may need to run
+`pod repo update` before the `pod gen` command.
+
+Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for
+those platforms. Since 10.2, Xcode does not properly handle multi-platform
+CocoaPods workspaces.
Firestore has a self contained Xcode project. See
[Firestore/README.md](Firestore/README.md).
+### Development for Catalyst
+* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`
+* Check the Mac box in the App-iOS Build Settings
+* Sign the App in the Settings Signing & Capabilities tab
+* Click Pods in the Project Manager
+* Add Signing to the iOS host app and unit test targets
+* Select the Unit-unit scheme
+* Run it to build and test
+
### Adding a New Firebase Pod
See [AddNewPod.md](AddNewPod.md).
@@ -98,13 +116,17 @@ Travis will verify that any code changes are done in a style compliant way. Inst
These commands will get the right versions:
```
-brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb
-brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/3dfea1004e0736754bbf49673cca8aaed8a94089/Formula/swiftformat.rb
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/e3496d9/Formula/clang-format.rb
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/7963c3d/Formula/swiftformat.rb
```
Note: if you already have a newer version of these installed you may need to
`brew switch` to this version.
+To update this section, find the versions of clang-format and swiftformat.rb to
+match the versions in the CI failure logs
+[here](https://github.com/Homebrew/homebrew-core/tree/master/Formula).
+
### Running Unit Tests
Select a scheme and press Command-u to build a component and run its unit tests.
@@ -177,34 +199,42 @@ We've seen an amazing amount of interest and contributions to improve the Fireba
very grateful! We'd like to empower as many developers as we can to be able to use Firebase and
participate in the Firebase community.
-### macOS and tvOS
-Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
-FirebaseDatabase, FirebaseMessaging,
-FirebaseFirestore, FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on
-macOS and tvOS.
+### tvOS, macOS, and Catalyst
+Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and work on
+tvOS, macOS, and Catalyst.
For tvOS, checkout the [Sample](Example/tvOSSample).
-Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is
-actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there
-may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter
-this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues).
+Keep in mind that macOS, Catalyst and tvOS are not officially supported by Firebase, and this
+repository is actively developed primarily for iOS. While we can catch basic unit test issues with
+Travis, there may be some changes where the SDK no longer works as expected on macOS or tvOS. If you
+encounter this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues).
-Note that the Firebase pod is not available for macOS and tvOS.
+During app setup in the console, you may get to a step that mentions something like "Checking if the app
+has communicated with our servers". This relies on Analytics and will not work on macOS/tvOS/Catalyst.
+**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected.
To install, add a subset of the following to the Podfile:
```
-pod 'FirebaseABTesting'
-pod 'FirebaseAuth'
-pod 'FirebaseCore'
-pod 'FirebaseDatabase'
-pod 'FirebaseFirestore'
-pod 'FirebaseFunctions'
-pod 'FirebaseMessaging'
-pod 'FirebaseStorage'
+pod 'Firebase/ABTesting'
+pod 'Firebase/Auth'
+pod 'Firebase/Crashlytics'
+pod 'Firebase/Database'
+pod 'Firebase/Firestore'
+pod 'Firebase/Functions'
+pod 'Firebase/Messaging'
+pod 'Firebase/RemoteConfig'
+pod 'Firebase/Storage'
```
+#### Additional Catalyst Notes
+
+* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`
+to Build Settings.
+* FirebaseFirestore requires signing the
+[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).
+
## Roadmap
See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source
diff --git a/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnostics.m b/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnostics.m
index 8f87e0929..bb0326be1 100644
--- a/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnostics.m
+++ b/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnostics.m
@@ -17,12 +17,13 @@
#import
#include
-#import
-#import
-#import
-#import
+#import
+#import
+#import
+#import
#import
+#import
#import
#import
@@ -34,8 +35,6 @@
#import "FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.h"
-#import "FIRCDLibrary/FIRCoreDiagnosticsDateFileStorage.h"
-
/** The logger service string to use when printing to the console. */
static GULLoggerService kFIRCoreDiagnostics = @"[FirebaseCoreDiagnostics/FIRCoreDiagnostics]";
@@ -85,6 +84,7 @@ static NSString *const kFIRAppDiagnosticsConfigurationTypeKey =
static NSString *const kFIRAppDiagnosticsFIRAppKey = @"FIRAppDiagnosticsFIRAppKey";
static NSString *const kFIRAppDiagnosticsSDKNameKey = @"FIRAppDiagnosticsSDKNameKey";
static NSString *const kFIRAppDiagnosticsSDKVersionKey = @"FIRAppDiagnosticsSDKVersionKey";
+static NSString *const kFIRCoreDiagnosticsHeartbeatTag = @"FIRCoreDiagnostics";
/**
* The file name to the recent heartbeat date.
@@ -92,7 +92,8 @@ static NSString *const kFIRAppDiagnosticsSDKVersionKey = @"FIRAppDiagnosticsSDKV
NSString *const kFIRCoreDiagnosticsHeartbeatDateFileName = @"FIREBASE_DIAGNOSTICS_HEARTBEAT_DATE";
/**
- * @note This should implement the GDTEventDataObject protocol, but can't because of weak-linking.
+ * @note This should implement the GDTCOREventDataObject protocol, but can't because of
+ * weak-linking.
*/
@interface FIRCoreDiagnosticsLog : NSObject
@@ -111,14 +112,14 @@ NSString *const kFIRCoreDiagnosticsHeartbeatDateFileName = @"FIREBASE_DIAGNOSTIC
return self;
}
-// Provided and required by the GDTEventDataObject protocol.
+// Provided and required by the GDTCOREventDataObject protocol.
- (NSData *)transportBytes {
pb_ostream_t sizestream = PB_OSTREAM_SIZING;
// Encode 1 time to determine the size.
if (!pb_encode(&sizestream, logs_proto_mobilesdk_ios_ICoreConfiguration_fields, &_config)) {
- GDTLogError(GDTMCETransportBytesError, @"Error in nanopb encoding for size: %s",
- PB_GET_ERROR(&sizestream));
+ GDTCORLogError(GDTCORMCETransportBytesError, @"Error in nanopb encoding for size: %s",
+ PB_GET_ERROR(&sizestream));
}
// Encode a 2nd time to actually get the bytes from it.
@@ -126,8 +127,8 @@ NSString *const kFIRCoreDiagnosticsHeartbeatDateFileName = @"FIREBASE_DIAGNOSTIC
CFMutableDataRef dataRef = CFDataCreateMutable(CFAllocatorGetDefault(), bufferSize);
pb_ostream_t ostream = pb_ostream_from_buffer((void *)CFDataGetBytePtr(dataRef), bufferSize);
if (!pb_encode(&ostream, logs_proto_mobilesdk_ios_ICoreConfiguration_fields, &_config)) {
- GDTLogError(GDTMCETransportBytesError, @"Error in nanopb encoding for bytes: %s",
- PB_GET_ERROR(&ostream));
+ GDTCORLogError(GDTCORMCETransportBytesError, @"Error in nanopb encoding for bytes: %s",
+ PB_GET_ERROR(&ostream));
}
CFDataSetLength(dataRef, ostream.bytes_written);
@@ -149,10 +150,10 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) dispatch_queue_t diagnosticsQueue;
/** The transport object used to send data. */
-@property(nonatomic, readonly) GDTTransport *transport;
+@property(nonatomic, readonly) GDTCORTransport *transport;
/** The storage to store the date of the last sent heartbeat. */
-@property(nonatomic, readonly) FIRCoreDiagnosticsDateFileStorage *heartbeatDateStorage;
+@property(nonatomic, readonly) GULHeartbeatDateStorage *heartbeatDateStorage;
@end
@@ -170,24 +171,24 @@ NS_ASSUME_NONNULL_END
}
- (instancetype)init {
- GDTTransport *transport = [[GDTTransport alloc] initWithMappingID:@"137"
- transformers:nil
- target:kGDTTargetCCT];
+ GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@"137"
+ transformers:nil
+ target:kGDTCORTargetFLL];
- FIRCoreDiagnosticsDateFileStorage *dateStorage = [[FIRCoreDiagnosticsDateFileStorage alloc]
- initWithFileURL:[[self class] filePathURLWithName:kFIRCoreDiagnosticsHeartbeatDateFileName]];
+ GULHeartbeatDateStorage *dateStorage =
+ [[GULHeartbeatDateStorage alloc] initWithFileName:kFIRCoreDiagnosticsHeartbeatDateFileName];
return [self initWithTransport:transport heartbeatDateStorage:dateStorage];
}
/** Initializer for unit tests.
*
- * @param transport A `GDTTransport` instance which that be used to send event.
+ * @param transport A `GDTCORTransport` instance which that be used to send event.
* @param heartbeatDateStorage An instanse of date storage to track heartbeat sending.
* @return Returns the initialized `FIRCoreDiagnostics` instance.
*/
-- (instancetype)initWithTransport:(GDTTransport *)transport
- heartbeatDateStorage:(FIRCoreDiagnosticsDateFileStorage *)heartbeatDateStorage {
+- (instancetype)initWithTransport:(GDTCORTransport *)transport
+ heartbeatDateStorage:(GULHeartbeatDateStorage *)heartbeatDateStorage {
self = [super init];
if (self) {
_diagnosticsQueue =
@@ -198,37 +199,6 @@ NS_ASSUME_NONNULL_END
return self;
}
-#pragma mark - File path helpers
-
-/** Returns the URL path of the file with name fileName under the Application Support folder for
- * local logging. Creates the Application Support folder if the folder doesn't exist.
- *
- * @return the URL path of the file with the name fileName in Application Support.
- */
-+ (NSURL *)filePathURLWithName:(NSString *)fileName {
- @synchronized(self) {
- NSArray *paths =
- NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
- NSArray *components = @[ paths.lastObject, @"Google/FIRApp" ];
- NSString *directoryString = [NSString pathWithComponents:components];
- NSURL *directoryURL = [NSURL fileURLWithPath:directoryString];
-
- NSError *error;
- if (![directoryURL checkResourceIsReachableAndReturnError:&error]) {
- // If fail creating the Application Support directory, return nil.
- if (![[NSFileManager defaultManager] createDirectoryAtURL:directoryURL
- withIntermediateDirectories:YES
- attributes:nil
- error:&error]) {
- GULLogWarning(kFIRCoreDiagnostics, YES, @"I-COR100001",
- @"Unable to create internal state storage: %@", error);
- return nil;
- }
- }
- return [directoryURL URLByAppendingPathComponent:fileName];
- }
-}
-
#pragma mark - Metadata helpers
/** Returns the model of iOS device. Sample platform strings are @"iPhone7,1" for iPhone 6 Plus,
@@ -374,7 +344,8 @@ void FIRPopulateProtoWithCommonInfoFromApp(logs_proto_mobilesdk_ios_ICoreConfigu
config->has_pod_name = 1;
if (!diagnosticObjects[kFIRCDllAppsCountKey]) {
- GDTLogError(GDTMCEGeneralError, @"%@", @"App count is a required value in the data dict.");
+ GDTCORLogError(GDTCORMCEGeneralError, @"%@",
+ @"App count is a required value in the data dict.");
}
config->app_count = (int32_t)[diagnosticObjects[kFIRCDllAppsCountKey] integerValue];
config->has_app_count = 1;
@@ -635,8 +606,8 @@ void FIRPopulateProtoWithInfoPlistValues(logs_proto_mobilesdk_ios_ICoreConfigura
FIRCoreDiagnosticsLog *log = [[FIRCoreDiagnosticsLog alloc] initWithConfig:icore_config];
// Send the log as a telemetry event.
- GDTEvent *event = [self.transport eventForTransport];
- event.dataObject = (id)log;
+ GDTCOREvent *event = [self.transport eventForTransport];
+ event.dataObject = (id)log;
[self.transport sendTelemetryEvent:event];
});
}
@@ -646,7 +617,8 @@ void FIRPopulateProtoWithInfoPlistValues(logs_proto_mobilesdk_ios_ICoreConfigura
- (void)setHeartbeatFlagIfNeededToConfig:(logs_proto_mobilesdk_ios_ICoreConfiguration *)config {
// Check if need to send a heartbeat.
NSDate *currentDate = [NSDate date];
- NSDate *lastCheckin = [self.heartbeatDateStorage date];
+ NSDate *lastCheckin =
+ [self.heartbeatDateStorage heartbeatDateForTag:kFIRCoreDiagnosticsHeartbeatTag];
if (lastCheckin) {
// Ensure the previous checkin was on a different date in the past.
if ([self isDate:currentDate inSameDayOrBeforeThan:lastCheckin]) {
@@ -655,12 +627,7 @@ void FIRPopulateProtoWithInfoPlistValues(logs_proto_mobilesdk_ios_ICoreConfigura
}
// Update heartbeat sent date.
- NSError *error;
- if (![self.heartbeatDateStorage setDate:currentDate error:&error]) {
- GULLogError(kFIRCoreDiagnostics, NO, @"I-COR100004", @"Unable to persist internal state: %@",
- error);
- }
-
+ [self.heartbeatDateStorage setHearbeatDate:currentDate forTag:kFIRCoreDiagnosticsHeartbeatTag];
// Set the flag.
config->sdk_name = logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_ICORE;
config->has_sdk_name = 1;
diff --git a/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnosticsDateFileStorage.m b/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnosticsDateFileStorage.m
deleted file mode 100644
index f4dca12a7..000000000
--- a/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/FIRCoreDiagnosticsDateFileStorage.m
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "FIRCDLibrary/FIRCoreDiagnosticsDateFileStorage.h"
-
-@interface FIRCoreDiagnosticsDateFileStorage ()
-@property(nonatomic, readonly) NSURL *fileURL;
-@end
-
-@implementation FIRCoreDiagnosticsDateFileStorage
-
-- (instancetype)initWithFileURL:(NSURL *)fileURL {
- if (fileURL == nil) {
- return nil;
- }
-
- self = [super init];
- if (self) {
- _fileURL = fileURL;
- }
-
- return self;
-}
-
-- (BOOL)setDate:(nullable NSDate *)date error:(NSError **)outError {
- NSString *stringToSave = @"";
-
- if (date != nil) {
- NSTimeInterval timestamp = [date timeIntervalSinceReferenceDate];
- stringToSave = [NSString stringWithFormat:@"%f", timestamp];
- }
-
- return [stringToSave writeToURL:self.fileURL
- atomically:YES
- encoding:NSUTF8StringEncoding
- error:outError];
-}
-
-- (nullable NSDate *)date {
- NSString *timestampString = [NSString stringWithContentsOfURL:self.fileURL
- encoding:NSUTF8StringEncoding
- error:nil];
- if (timestampString.length == 0) {
- return nil;
- }
-
- NSTimeInterval timestamp = timestampString.doubleValue;
- return [NSDate dateWithTimeIntervalSinceReferenceDate:timestamp];
-}
-
-@end
diff --git a/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.c b/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.c
index 3c35ffb1d..4b2ac2f74 100644
--- a/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.c
+++ b/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.c
@@ -15,7 +15,7 @@
*/
/* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.3.9.2 */
+/* Generated by nanopb-0.3.9.3 */
#include "firebasecore.nanopb.h"
@@ -26,28 +26,19 @@
-const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[34] = {
+const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[22] = {
PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, logs_proto_mobilesdk_ios_ICoreConfiguration, configuration_type, configuration_type, 0),
- PB_FIELD( 2, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, version_name, configuration_type, 0),
- PB_FIELD( 3, INT64 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, build_number, version_name, 0),
- PB_FIELD( 4, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, build_type, build_number, 0),
- PB_FIELD( 5, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, plist_version, build_type, 0),
- PB_FIELD( 6, UENUM , REPEATED, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_service_enabled, plist_version, 0),
- PB_FIELD( 7, UENUM , REPEATED, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_service_installed, sdk_service_enabled, 0),
+ PB_FIELD( 7, UENUM , REPEATED, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_service_installed, configuration_type, 0),
PB_FIELD( 9, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, device_model, sdk_service_installed, 0),
PB_FIELD( 10, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, app_id, device_model, 0),
- PB_FIELD( 11, INT64 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, project_number, app_id, 0),
- PB_FIELD( 12, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, bundle_id, project_number, 0),
- PB_FIELD( 13, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, client_id, bundle_id, 0),
- PB_FIELD( 14, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, install, client_id, 0),
- PB_FIELD( 16, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, pod_name, install, 0),
+ PB_FIELD( 12, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, bundle_id, app_id, 0),
+ PB_FIELD( 16, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, pod_name, bundle_id, 0),
PB_FIELD( 18, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, icore_version, pod_name, 0),
PB_FIELD( 19, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_version, icore_version, 0),
PB_FIELD( 20, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_name, sdk_version, 0),
PB_FIELD( 21, INT32 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, app_count, sdk_name, 0),
PB_FIELD( 22, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, os_version, app_count, 0),
- PB_FIELD( 23, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, itunes_id, os_version, 0),
- PB_FIELD( 24, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, min_supported_ios_version, itunes_id, 0),
+ PB_FIELD( 24, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, min_supported_ios_version, os_version, 0),
PB_FIELD( 25, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, use_default_app, min_supported_ios_version, 0),
PB_FIELD( 26, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, deployed_in_app_store, use_default_app, 0),
PB_FIELD( 27, INT32 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, dynamic_framework_count, deployed_in_app_store, 0),
@@ -55,11 +46,8 @@ const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[34] = {
PB_FIELD( 29, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, using_zip_file, apple_framework_version, 0),
PB_FIELD( 30, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, deployment_type, using_zip_file, 0),
PB_FIELD( 31, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, platform_info, deployment_type, 0),
- PB_FIELD( 32, INT64 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, app_extensions, platform_info, 0),
- PB_FIELD( 33, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, swizzling_enabled, app_extensions, 0),
- PB_FIELD( 34, INT32 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, log_error_count, swizzling_enabled, 0),
- PB_FIELD( 35, INT32 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, log_warning_count, log_error_count, 0),
- PB_FIELD( 36, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, using_gdt, log_warning_count, 0),
+ PB_FIELD( 33, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, swizzling_enabled, platform_info, 0),
+ PB_FIELD( 36, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, using_gdt, swizzling_enabled, 0),
PB_LAST_FIELD
};
diff --git a/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.h b/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.h
index 41059e5d9..3e4c1950d 100644
--- a/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.h
+++ b/ios/Pods/FirebaseCoreDiagnostics/Firebase/CoreDiagnostics/FIRCDLibrary/Protogen/nanopb/firebasecore.nanopb.h
@@ -15,7 +15,7 @@
*/
/* Automatically generated nanopb header */
-/* Generated by nanopb-0.3.9.2 */
+/* Generated by nanopb-0.3.9.3 */
#ifndef PB_LOGS_PROTO_MOBILESDK_IOS_FIREBASECORE_NANOPB_H_INCLUDED
#define PB_LOGS_PROTO_MOBILESDK_IOS_FIREBASECORE_NANOPB_H_INCLUDED
@@ -111,23 +111,11 @@ typedef enum _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType {
typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
bool has_configuration_type;
logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType configuration_type;
- pb_bytes_array_t *version_name;
- bool has_build_number;
- int64_t build_number;
- bool has_build_type;
- logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType build_type;
- pb_bytes_array_t *plist_version;
- pb_size_t sdk_service_enabled_count;
- logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType *sdk_service_enabled;
pb_size_t sdk_service_installed_count;
logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType *sdk_service_installed;
pb_bytes_array_t *device_model;
pb_bytes_array_t *app_id;
- bool has_project_number;
- int64_t project_number;
pb_bytes_array_t *bundle_id;
- pb_bytes_array_t *client_id;
- pb_bytes_array_t *install;
bool has_pod_name;
logs_proto_mobilesdk_ios_ICoreConfiguration_PodName pod_name;
pb_bytes_array_t *icore_version;
@@ -137,7 +125,6 @@ typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
bool has_app_count;
int32_t app_count;
pb_bytes_array_t *os_version;
- pb_bytes_array_t *itunes_id;
pb_bytes_array_t *min_supported_ios_version;
bool has_use_default_app;
bool use_default_app;
@@ -151,14 +138,8 @@ typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
bool has_deployment_type;
logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType deployment_type;
pb_bytes_array_t *platform_info;
- bool has_app_extensions;
- int64_t app_extensions;
bool has_swizzling_enabled;
bool swizzling_enabled;
- bool has_log_error_count;
- int32_t log_error_count;
- bool has_log_warning_count;
- int32_t log_warning_count;
bool has_using_gdt;
bool using_gdt;
/* @@protoc_insertion_point(struct:logs_proto_mobilesdk_ios_ICoreConfiguration) */
@@ -167,30 +148,21 @@ typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
/* Default values for struct fields */
/* Initializer values for message structs */
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_default {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_MIN, NULL, 0, NULL, 0, NULL, NULL, NULL, false, 0, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0, false, 0, false, 0, false, 0}
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_zero {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_MIN, NULL, 0, NULL, 0, NULL, NULL, NULL, false, 0, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0, false, 0, false, 0, false, 0}
+#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_default {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, 0, NULL, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0}
+#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_zero {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, 0, NULL, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0}
/* Field tags (for use in manual encoding/decoding) */
#define logs_proto_mobilesdk_ios_ICoreConfiguration_pod_name_tag 16
#define logs_proto_mobilesdk_ios_ICoreConfiguration_configuration_type_tag 1
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_version_name_tag 2
#define logs_proto_mobilesdk_ios_ICoreConfiguration_icore_version_tag 18
#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_version_tag 19
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_build_number_tag 3
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_build_type_tag 4
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_plist_version_tag 5
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_service_enabled_tag 6
#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_service_installed_tag 7
#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_name_tag 20
#define logs_proto_mobilesdk_ios_ICoreConfiguration_device_model_tag 9
#define logs_proto_mobilesdk_ios_ICoreConfiguration_os_version_tag 22
#define logs_proto_mobilesdk_ios_ICoreConfiguration_app_id_tag 10
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_project_number_tag 11
#define logs_proto_mobilesdk_ios_ICoreConfiguration_bundle_id_tag 12
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_client_id_tag 13
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_itunes_id_tag 23
#define logs_proto_mobilesdk_ios_ICoreConfiguration_min_supported_ios_version_tag 24
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_install_tag 14
#define logs_proto_mobilesdk_ios_ICoreConfiguration_use_default_app_tag 25
#define logs_proto_mobilesdk_ios_ICoreConfiguration_app_count_tag 21
#define logs_proto_mobilesdk_ios_ICoreConfiguration_deployed_in_app_store_tag 26
@@ -199,14 +171,11 @@ typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
#define logs_proto_mobilesdk_ios_ICoreConfiguration_using_zip_file_tag 29
#define logs_proto_mobilesdk_ios_ICoreConfiguration_deployment_type_tag 30
#define logs_proto_mobilesdk_ios_ICoreConfiguration_platform_info_tag 31
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_app_extensions_tag 32
#define logs_proto_mobilesdk_ios_ICoreConfiguration_swizzling_enabled_tag 33
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_log_error_count_tag 34
-#define logs_proto_mobilesdk_ios_ICoreConfiguration_log_warning_count_tag 35
#define logs_proto_mobilesdk_ios_ICoreConfiguration_using_gdt_tag 36
/* Struct field encoding specification for nanopb */
-extern const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[34];
+extern const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[22];
/* Maximum encoded size of messages (where known) */
/* logs_proto_mobilesdk_ios_ICoreConfiguration_size depends on runtime parameters */
diff --git a/ios/Pods/FirebaseCoreDiagnostics/README.md b/ios/Pods/FirebaseCoreDiagnostics/README.md
index bf397f057..3ddc8fbd2 100644
--- a/ios/Pods/FirebaseCoreDiagnostics/README.md
+++ b/ios/Pods/FirebaseCoreDiagnostics/README.md
@@ -1,9 +1,10 @@
# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk)
This repository contains a subset of the Firebase iOS SDK source. It currently
-includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore,
-FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
-FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage.
+includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
+FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
+FirebaseInAppMessagingDisplay, FirebaseMessaging, FirebaseRemoteConfig, and
+FirebaseStorage.
The repository also includes GoogleUtilities source. The
[GoogleUtilities](GoogleUtilities/README.md) pod is
@@ -75,14 +76,30 @@ the following software:
* Xcode 10.1 (or later)
* CocoaPods 1.7.2 (or later)
+ * [CocoaPods generate](https://github.com/square/cocoapods-generate)
For the pod that you want to develop:
-`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open`
+`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios`
-Firestore and Functions have self contained Xcode projects. See
-[Firestore/README.md](Firestore/README.md) and
-[Functions/README.md](Functions/README.md).
+Note: If the CocoaPods cache is out of date, you may need to run
+`pod repo update` before the `pod gen` command.
+
+Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for
+those platforms. Since 10.2, Xcode does not properly handle multi-platform
+CocoaPods workspaces.
+
+Firestore has a self contained Xcode project. See
+[Firestore/README.md](Firestore/README.md).
+
+### Development for Catalyst
+* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`
+* Check the Mac box in the App-iOS Build Settings
+* Sign the App in the Settings Signing & Capabilities tab
+* Click Pods in the Project Manager
+* Add Signing to the iOS host app and unit test targets
+* Select the Unit-unit scheme
+* Run it to build and test
### Adding a New Firebase Pod
@@ -99,13 +116,17 @@ Travis will verify that any code changes are done in a style compliant way. Inst
These commands will get the right versions:
```
-brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb
-brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/3dfea1004e0736754bbf49673cca8aaed8a94089/Formula/swiftformat.rb
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/e3496d9/Formula/clang-format.rb
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/7963c3d/Formula/swiftformat.rb
```
Note: if you already have a newer version of these installed you may need to
`brew switch` to this version.
+To update this section, find the versions of clang-format and swiftformat.rb to
+match the versions in the CI failure logs
+[here](https://github.com/Homebrew/homebrew-core/tree/master/Formula).
+
### Running Unit Tests
Select a scheme and press Command-u to build a component and run its unit tests.
@@ -178,32 +199,39 @@ We've seen an amazing amount of interest and contributions to improve the Fireba
very grateful! We'd like to empower as many developers as we can to be able to use Firebase and
participate in the Firebase community.
-### macOS and tvOS
-Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, FirebaseMessaging,
-FirebaseFirestore, FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on
-macOS and tvOS.
+### tvOS, macOS, and Catalyst
+Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
+FirebaseDatabase, FirebaseMessaging, FirebaseFirestore,
+FirebaseFunctions, FirebaseRemoteConfig, and FirebaseStorage now compile, run unit tests, and work on
+tvOS, macOS, and Catalyst.
For tvOS, checkout the [Sample](Example/tvOSSample).
-Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is
-actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there
-may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter
-this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues).
-
-Note that the Firebase pod is not available for macOS and tvOS.
+Keep in mind that macOS, Catalyst and tvOS are not officially supported by Firebase, and this
+repository is actively developed primarily for iOS. While we can catch basic unit test issues with
+Travis, there may be some changes where the SDK no longer works as expected on macOS or tvOS. If you
+encounter this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues).
To install, add a subset of the following to the Podfile:
```
-pod 'FirebaseAuth'
-pod 'FirebaseCore'
-pod 'FirebaseDatabase'
-pod 'FirebaseFirestore'
-pod 'FirebaseFunctions'
-pod 'FirebaseMessaging'
-pod 'FirebaseStorage'
+pod 'Firebase/ABTesting'
+pod 'Firebase/Auth'
+pod 'Firebase/Database'
+pod 'Firebase/Firestore'
+pod 'Firebase/Functions'
+pod 'Firebase/Messaging'
+pod 'Firebase/RemoteConfig'
+pod 'Firebase/Storage'
```
+#### Additional Catalyst Notes
+
+* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`
+to Build Settings.
+* FirebaseFirestore requires signing the
+[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).
+
## Roadmap
See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source
diff --git a/ios/Pods/FirebaseCoreDiagnosticsInterop/Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h b/ios/Pods/FirebaseCoreDiagnosticsInterop/Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h
index 7c7477696..69c40721a 100644
--- a/ios/Pods/FirebaseCoreDiagnosticsInterop/Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h
+++ b/ios/Pods/FirebaseCoreDiagnosticsInterop/Interop/CoreDiagnostics/Public/FIRCoreDiagnosticsData.h
@@ -19,36 +19,34 @@
NS_ASSUME_NONNULL_BEGIN
/** If present, is a BOOL wrapped in an NSNumber. */
-static NSString *const kFIRCDIsDataCollectionDefaultEnabledKey =
- @"FIRCDIsDataCollectionDefaultEnabledKey";
+#define kFIRCDIsDataCollectionDefaultEnabledKey @"FIRCDIsDataCollectionDefaultEnabledKey"
/** If present, is an int32_t wrapped in an NSNumber. */
-static NSString *const kFIRCDConfigurationTypeKey = @"FIRCDConfigurationTypeKey";
+#define kFIRCDConfigurationTypeKey @"FIRCDConfigurationTypeKey"
/** If present, is an NSString. */
-static NSString *const kFIRCDSdkNameKey = @"FIRCDSdkNameKey";
+#define kFIRCDSdkNameKey @"FIRCDSdkNameKey"
/** If present, is an NSString. */
-static NSString *const kFIRCDSdkVersionKey = @"FIRCDSdkVersionKey";
+#define kFIRCDSdkVersionKey @"FIRCDSdkVersionKey"
/** If present, is an int32_t wrapped in an NSNumber. */
-static NSString *const kFIRCDllAppsCountKey = @"FIRCDllAppsCountKey";
+#define kFIRCDllAppsCountKey @"FIRCDllAppsCountKey"
/** If present, is an NSString. */
-static NSString *const kFIRCDGoogleAppIDKey = @"FIRCDGoogleAppIDKey";
+#define kFIRCDGoogleAppIDKey @"FIRCDGoogleAppIDKey"
/** If present, is an NSString. */
-static NSString *const kFIRCDBundleIDKey = @"FIRCDBundleID";
+#define kFIRCDBundleIDKey @"FIRCDBundleID"
/** If present, is a BOOL wrapped in an NSNumber. */
-static NSString *const kFIRCDUsingOptionsFromDefaultPlistKey =
- @"FIRCDUsingOptionsFromDefaultPlistKey";
+#define kFIRCDUsingOptionsFromDefaultPlistKey @"FIRCDUsingOptionsFromDefaultPlistKey"
/** If present, is an NSString. */
-static NSString *const kFIRCDLibraryVersionIDKey = @"FIRCDLibraryVersionIDKey";
+#define kFIRCDLibraryVersionIDKey @"FIRCDLibraryVersionIDKey"
/** If present, is an NSString. */
-static NSString *const kFIRCDFirebaseUserAgentKey = @"FIRCDFirebaseUserAgentKey";
+#define kFIRCDFirebaseUserAgentKey @"FIRCDFirebaseUserAgentKey"
/** Defines the interface of a data object needed to log diagnostics data. */
@protocol FIRCoreDiagnosticsData
diff --git a/ios/Pods/FirebaseCoreDiagnosticsInterop/README.md b/ios/Pods/FirebaseCoreDiagnosticsInterop/README.md
index bf397f057..3ddc8fbd2 100644
--- a/ios/Pods/FirebaseCoreDiagnosticsInterop/README.md
+++ b/ios/Pods/FirebaseCoreDiagnosticsInterop/README.md
@@ -1,9 +1,10 @@
# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk)
This repository contains a subset of the Firebase iOS SDK source. It currently
-includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore,
-FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
-FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage.
+includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
+FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
+FirebaseInAppMessagingDisplay, FirebaseMessaging, FirebaseRemoteConfig, and
+FirebaseStorage.
The repository also includes GoogleUtilities source. The
[GoogleUtilities](GoogleUtilities/README.md) pod is
@@ -75,14 +76,30 @@ the following software:
* Xcode 10.1 (or later)
* CocoaPods 1.7.2 (or later)
+ * [CocoaPods generate](https://github.com/square/cocoapods-generate)
For the pod that you want to develop:
-`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open`
+`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios`
-Firestore and Functions have self contained Xcode projects. See
-[Firestore/README.md](Firestore/README.md) and
-[Functions/README.md](Functions/README.md).
+Note: If the CocoaPods cache is out of date, you may need to run
+`pod repo update` before the `pod gen` command.
+
+Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for
+those platforms. Since 10.2, Xcode does not properly handle multi-platform
+CocoaPods workspaces.
+
+Firestore has a self contained Xcode project. See
+[Firestore/README.md](Firestore/README.md).
+
+### Development for Catalyst
+* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`
+* Check the Mac box in the App-iOS Build Settings
+* Sign the App in the Settings Signing & Capabilities tab
+* Click Pods in the Project Manager
+* Add Signing to the iOS host app and unit test targets
+* Select the Unit-unit scheme
+* Run it to build and test
### Adding a New Firebase Pod
@@ -99,13 +116,17 @@ Travis will verify that any code changes are done in a style compliant way. Inst
These commands will get the right versions:
```
-brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb
-brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/3dfea1004e0736754bbf49673cca8aaed8a94089/Formula/swiftformat.rb
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/e3496d9/Formula/clang-format.rb
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/7963c3d/Formula/swiftformat.rb
```
Note: if you already have a newer version of these installed you may need to
`brew switch` to this version.
+To update this section, find the versions of clang-format and swiftformat.rb to
+match the versions in the CI failure logs
+[here](https://github.com/Homebrew/homebrew-core/tree/master/Formula).
+
### Running Unit Tests
Select a scheme and press Command-u to build a component and run its unit tests.
@@ -178,32 +199,39 @@ We've seen an amazing amount of interest and contributions to improve the Fireba
very grateful! We'd like to empower as many developers as we can to be able to use Firebase and
participate in the Firebase community.
-### macOS and tvOS
-Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, FirebaseMessaging,
-FirebaseFirestore, FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on
-macOS and tvOS.
+### tvOS, macOS, and Catalyst
+Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
+FirebaseDatabase, FirebaseMessaging, FirebaseFirestore,
+FirebaseFunctions, FirebaseRemoteConfig, and FirebaseStorage now compile, run unit tests, and work on
+tvOS, macOS, and Catalyst.
For tvOS, checkout the [Sample](Example/tvOSSample).
-Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is
-actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there
-may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter
-this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues).
-
-Note that the Firebase pod is not available for macOS and tvOS.
+Keep in mind that macOS, Catalyst and tvOS are not officially supported by Firebase, and this
+repository is actively developed primarily for iOS. While we can catch basic unit test issues with
+Travis, there may be some changes where the SDK no longer works as expected on macOS or tvOS. If you
+encounter this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues).
To install, add a subset of the following to the Podfile:
```
-pod 'FirebaseAuth'
-pod 'FirebaseCore'
-pod 'FirebaseDatabase'
-pod 'FirebaseFirestore'
-pod 'FirebaseFunctions'
-pod 'FirebaseMessaging'
-pod 'FirebaseStorage'
+pod 'Firebase/ABTesting'
+pod 'Firebase/Auth'
+pod 'Firebase/Database'
+pod 'Firebase/Firestore'
+pod 'Firebase/Functions'
+pod 'Firebase/Messaging'
+pod 'Firebase/RemoteConfig'
+pod 'Firebase/Storage'
```
+#### Additional Catalyst Notes
+
+* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`
+to Build Settings.
+* FirebaseFirestore requires signing the
+[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).
+
## Roadmap
See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h
new file mode 100644
index 000000000..5bc21a11c
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+#import
+
+@class FIRInstallationsHTTPError;
+
+NS_ASSUME_NONNULL_BEGIN
+
+void FIRInstallationsItemSetErrorToPointer(NSError *error, NSError **pointer);
+
+@interface FIRInstallationsErrorUtil : NSObject
+
++ (NSError *)keyedArchiverErrorWithException:(NSException *)exception;
++ (NSError *)keyedArchiverErrorWithError:(NSError *)error;
+
++ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status;
+
++ (NSError *)installationItemNotFoundForAppID:(NSString *)appID appName:(NSString *)appName;
+
++ (NSError *)JSONSerializationError:(NSError *)error;
+
++ (NSError *)networkErrorWithError:(NSError *)error;
+
++ (NSError *)FIDRegistrationErrorWithResponseMissingField:(NSString *)missingFieldName;
+
++ (NSError *)corruptedIIDTokenData;
+
++ (FIRInstallationsHTTPError *)APIErrorWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse
+ data:(nullable NSData *)data;
++ (BOOL)isAPIError:(NSError *)error withHTTPCode:(NSInteger)HTTPCode;
+
+/**
+ * Returns the passed error if it is already in the public domain or a new error with the passed
+ * error at `NSUnderlyingErrorKey`.
+ */
++ (NSError *)publicDomainErrorWithError:(NSError *)error;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m
new file mode 100644
index 000000000..f85923ace
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsErrorUtil.h"
+
+#import "FIRInstallationsHTTPError.h"
+
+NSString *const kFirebaseInstallationsErrorDomain = @"com.firebase.installations";
+
+void FIRInstallationsItemSetErrorToPointer(NSError *error, NSError **pointer) {
+ if (pointer != NULL) {
+ *pointer = error;
+ }
+}
+
+@implementation FIRInstallationsErrorUtil
+
++ (NSError *)keyedArchiverErrorWithException:(NSException *)exception {
+ NSString *failureReason = [NSString
+ stringWithFormat:@"NSKeyedArchiver exception with name: %@, reason: %@, userInfo: %@",
+ exception.name, exception.reason, exception.userInfo];
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown
+ failureReason:failureReason
+ underlyingError:nil];
+}
+
++ (NSError *)keyedArchiverErrorWithError:(NSError *)error {
+ NSString *failureReason = [NSString stringWithFormat:@"NSKeyedArchiver error."];
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown
+ failureReason:failureReason
+ underlyingError:error];
+}
+
++ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status {
+ NSString *failureReason = [NSString stringWithFormat:@"%@ (%li)", keychainFunction, (long)status];
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeKeychain
+ failureReason:failureReason
+ underlyingError:nil];
+}
+
++ (NSError *)installationItemNotFoundForAppID:(NSString *)appID appName:(NSString *)appName {
+ NSString *failureReason =
+ [NSString stringWithFormat:@"Installation for appID %@ appName %@ not found", appID, appName];
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown
+ failureReason:failureReason
+ underlyingError:nil];
+}
+
++ (NSError *)corruptedIIDTokenData {
+ NSString *failureReason =
+ @"IID token data stored in Keychain is corrupted or in an incompatible format.";
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown
+ failureReason:failureReason
+ underlyingError:nil];
+}
+
++ (FIRInstallationsHTTPError *)APIErrorWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse
+ data:(nullable NSData *)data {
+ return [[FIRInstallationsHTTPError alloc] initWithHTTPResponse:HTTPResponse data:data];
+}
+
++ (BOOL)isAPIError:(NSError *)error withHTTPCode:(NSInteger)HTTPCode {
+ if (![error isKindOfClass:[FIRInstallationsHTTPError class]]) {
+ return NO;
+ }
+
+ return [(FIRInstallationsHTTPError *)error HTTPResponse].statusCode == HTTPCode;
+}
+
++ (NSError *)JSONSerializationError:(NSError *)error {
+ NSString *failureReason = [NSString stringWithFormat:@"Failed to serialize JSON data."];
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown
+ failureReason:failureReason
+ underlyingError:nil];
+}
+
++ (NSError *)FIDRegistrationErrorWithResponseMissingField:(NSString *)missingFieldName {
+ NSString *failureReason = [NSString
+ stringWithFormat:@"A required response field with name %@ is missing", missingFieldName];
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown
+ failureReason:failureReason
+ underlyingError:nil];
+}
+
++ (NSError *)networkErrorWithError:(NSError *)error {
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeServerUnreachable
+ failureReason:@"Network connection error."
+ underlyingError:error];
+}
+
++ (NSError *)publicDomainErrorWithError:(NSError *)error {
+ if ([error.domain isEqualToString:kFirebaseInstallationsErrorDomain]) {
+ return error;
+ }
+
+ return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown
+ failureReason:nil
+ underlyingError:error];
+}
+
++ (NSError *)installationsErrorWithCode:(FIRInstallationsErrorCode)code
+ failureReason:(nullable NSString *)failureReason
+ underlyingError:(nullable NSError *)underlyingError {
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+ userInfo[NSUnderlyingErrorKey] = underlyingError;
+ userInfo[NSLocalizedFailureReasonErrorKey] = failureReason;
+
+ return [NSError errorWithDomain:kFirebaseInstallationsErrorDomain code:code userInfo:userInfo];
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h
new file mode 100644
index 000000000..ad0eb8c13
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+/** Represents an error caused by an unexpected API response. */
+@interface FIRInstallationsHTTPError : NSError
+
+@property(nonatomic, readonly) NSHTTPURLResponse *HTTPResponse;
+@property(nonatomic, readonly, nonnull) NSData *data;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+- (instancetype)initWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse data:(nullable NSData *)data;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+typedef NS_ENUM(NSInteger, FIRInstallationsHTTPCodes) {
+ FIRInstallationsHTTPCodesTooManyRequests = 429,
+ FIRInstallationsHTTPCodesServerInternalError = 500,
+};
+
+/** Possible response HTTP codes for `CreateInstallation` API request. */
+typedef NS_ENUM(NSInteger, FIRInstallationsRegistrationHTTPCode) {
+ FIRInstallationsRegistrationHTTPCodeSuccess = 201,
+ FIRInstallationsRegistrationHTTPCodeInvalidArgument = 400,
+ FIRInstallationsRegistrationHTTPCodeInvalidAPIKey = 401,
+ FIRInstallationsRegistrationHTTPCodeAPIKeyToProjectIDMismatch = 403,
+ FIRInstallationsRegistrationHTTPCodeProjectNotFound = 404,
+ FIRInstallationsRegistrationHTTPCodeTooManyRequests = 429,
+ FIRInstallationsRegistrationHTTPCodeServerInternalError = 500
+};
+
+typedef NS_ENUM(NSInteger, FIRInstallationsAuthTokenHTTPCode) {
+ FIRInstallationsAuthTokenHTTPCodeInvalidAuthentication = 401,
+ FIRInstallationsAuthTokenHTTPCodeFIDNotFound = 404,
+};
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m
new file mode 100644
index 000000000..5b3eae22b
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsHTTPError.h"
+#import "FIRInstallationsErrorUtil.h"
+
+@implementation FIRInstallationsHTTPError
+
+- (instancetype)initWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse
+ data:(nullable NSData *)data {
+ NSDictionary *userInfo = [FIRInstallationsHTTPError userInfoWithHTTPResponse:HTTPResponse
+ data:data];
+ self = [super
+ initWithDomain:kFirebaseInstallationsErrorDomain
+ code:[FIRInstallationsHTTPError errorCodeWithHTTPCode:HTTPResponse.statusCode]
+ userInfo:userInfo];
+ if (self) {
+ _HTTPResponse = HTTPResponse;
+ _data = data;
+ }
+ return self;
+}
+
++ (FIRInstallationsErrorCode)errorCodeWithHTTPCode:(NSInteger)HTTPCode {
+ return FIRInstallationsErrorCodeUnknown;
+}
+
++ (NSDictionary *)userInfoWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse
+ data:(nullable NSData *)data {
+ NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ NSString *failureReason = [NSString
+ stringWithFormat:@"The server responded with an error. HTTP response: %@\nResponse body: %@",
+ HTTPResponse, responseString];
+ return @{NSLocalizedFailureReasonErrorKey : failureReason};
+}
+
+#pragma mark - NSCopying
+
+- (id)copyWithZone:(NSZone *)zone {
+ return [[FIRInstallationsHTTPError alloc] initWithHTTPResponse:self.HTTPResponse data:self.data];
+}
+
+#pragma mark - NSSecureCoding
+
+- (nullable instancetype)initWithCoder:(NSCoder *)coder {
+ NSHTTPURLResponse *HTTPResponse = [coder decodeObjectOfClass:[NSHTTPURLResponse class]
+ forKey:@"HTTPResponse"];
+ if (!HTTPResponse) {
+ return nil;
+ }
+ NSData *data = [coder decodeObjectOfClass:[NSData class] forKey:@"data"];
+
+ return [self initWithHTTPResponse:HTTPResponse data:data];
+}
+
+- (void)encodeWithCoder:(NSCoder *)coder {
+ [coder encodeObject:self.HTTPResponse forKey:@"HTTPResponse"];
+ [coder encodeObject:self.data forKey:@"data"];
+}
+
++ (BOOL)supportsSecureCoding {
+ return YES;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallations.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallations.m
new file mode 100644
index 000000000..71e7dd434
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallations.m
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallations.h"
+
+#if __has_include()
+#import
+#else
+#import "FBLPromises.h"
+#endif
+
+#import
+#import
+#import
+#import
+#import
+#import
+
+#import "FIRInstallationsAuthTokenResultInternal.h"
+
+#import "FIRInstallationsErrorUtil.h"
+#import "FIRInstallationsIDController.h"
+#import "FIRInstallationsItem.h"
+#import "FIRInstallationsLogger.h"
+#import "FIRInstallationsStoredAuthToken.h"
+#import "FIRInstallationsVersion.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol FIRInstallationsInstanceProvider
+@end
+
+@interface FIRInstallations ()
+@property(nonatomic, readonly) FIROptions *appOptions;
+@property(nonatomic, readonly) NSString *appName;
+
+@property(nonatomic, readonly) FIRInstallationsIDController *installationsIDController;
+
+@end
+
+@implementation FIRInstallations
+
+#pragma mark - Firebase component
+
++ (void)load {
+ [FIRApp registerInternalLibrary:(Class)self
+ withName:@"fire-install"
+ withVersion:[NSString stringWithUTF8String:FIRInstallationsVersionStr]];
+}
+
++ (nonnull NSArray *)componentsToRegister {
+ FIRComponentCreationBlock creationBlock =
+ ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
+ *isCacheable = YES;
+ FIRInstallations *installations = [[FIRInstallations alloc] initWithApp:container.app];
+ return installations;
+ };
+
+ FIRComponent *installationsProvider =
+ [FIRComponent componentWithProtocol:@protocol(FIRInstallationsInstanceProvider)
+ instantiationTiming:FIRInstantiationTimingAlwaysEager
+ dependencies:@[]
+ creationBlock:creationBlock];
+ return @[ installationsProvider ];
+}
+
+- (instancetype)initWithApp:(FIRApp *)app {
+ return [self initWitAppOptions:app.options appName:app.name];
+}
+
+- (instancetype)initWitAppOptions:(FIROptions *)appOptions appName:(NSString *)appName {
+ FIRInstallationsIDController *IDController =
+ [[FIRInstallationsIDController alloc] initWithGoogleAppID:appOptions.googleAppID
+ appName:appName
+ APIKey:appOptions.APIKey
+ projectID:appOptions.projectID
+ GCMSenderID:appOptions.GCMSenderID
+ accessGroup:appOptions.appGroupID];
+ return [self initWithAppOptions:appOptions
+ appName:appName
+ installationsIDController:IDController
+ prefetchAuthToken:YES];
+}
+
+/// The initializer is supposed to be used by tests to inject `installationsStore`.
+- (instancetype)initWithAppOptions:(FIROptions *)appOptions
+ appName:(NSString *)appName
+ installationsIDController:(FIRInstallationsIDController *)installationsIDController
+ prefetchAuthToken:(BOOL)prefetchAuthToken {
+ self = [super init];
+ if (self) {
+ [[self class] validateAppOptions:appOptions appName:appName];
+ [[self class] assertCompatibleIIDVersion];
+
+ _appOptions = [appOptions copy];
+ _appName = [appName copy];
+ _installationsIDController = installationsIDController;
+
+ // Pre-fetch auth token.
+ if (prefetchAuthToken) {
+ [self authTokenWithCompletion:^(FIRInstallationsAuthTokenResult *_Nullable tokenResult,
+ NSError *_Nullable error){
+ }];
+ }
+ }
+ return self;
+}
+
++ (void)validateAppOptions:(FIROptions *)appOptions appName:(NSString *)appName {
+ NSMutableArray *missingFields = [NSMutableArray array];
+ if (appName.length < 1) {
+ [missingFields addObject:@"`FirebaseApp.name`"];
+ }
+ if (appOptions.APIKey.length < 1) {
+ [missingFields addObject:@"`FirebaseOptions.APIKey`"];
+ }
+ if (appOptions.googleAppID.length < 1) {
+ [missingFields addObject:@"`FirebaseOptions.googleAppID`"];
+ }
+
+ // TODO(#4692): Check for `appOptions.projectID.length < 1` only.
+ // We can use `GCMSenderID` instead of `projectID` temporary.
+ if (appOptions.projectID.length < 1 && appOptions.GCMSenderID.length < 1) {
+ [missingFields addObject:@"`FirebaseOptions.projectID`"];
+ }
+
+ if (missingFields.count > 0) {
+ [NSException
+ raise:kFirebaseInstallationsErrorDomain
+ format:
+ @"%@[%@] Could not configure Firebase Installations due to invalid FirebaseApp "
+ @"options. The following parameters are nil or empty: %@. If you use "
+ @"GoogleServices-Info.plist please download the most recent version from the Firebase "
+ @"Console. If you configure Firebase in code, please make sure you specify all "
+ @"required parameters.",
+ kFIRLoggerInstallations, kFIRInstallationsMessageCodeInvalidFirebaseAppOptions,
+ [missingFields componentsJoinedByString:@", "]];
+ }
+}
+
+#pragma mark - Public
+
++ (FIRInstallations *)installations {
+ FIRApp *defaultApp = [FIRApp defaultApp];
+ if (!defaultApp) {
+ [NSException raise:kFirebaseInstallationsErrorDomain
+ format:@"The default FirebaseApp instance must be configured before the default"
+ @"FirebaseApp instance can be initialized. One way to ensure that is to "
+ @"call `[FIRApp configure];` (`FirebaseApp.configure()` in Swift) in the App"
+ @" Delegate's `application:didFinishLaunchingWithOptions:` "
+ @"(`application(_:didFinishLaunchingWithOptions:)` in Swift)."];
+ }
+
+ return [self installationsWithApp:defaultApp];
+}
+
++ (FIRInstallations *)installationsWithApp:(FIRApp *)app {
+ id installations =
+ FIR_COMPONENT(FIRInstallationsInstanceProvider, app.container);
+ return (FIRInstallations *)installations;
+}
+
+- (void)installationIDWithCompletion:(FIRInstallationsIDHandler)completion {
+ [self.installationsIDController getInstallationItem]
+ .then(^id(FIRInstallationsItem *installation) {
+ completion(installation.firebaseInstallationID, nil);
+ return nil;
+ })
+ .catch(^(NSError *error) {
+ completion(nil, [FIRInstallationsErrorUtil publicDomainErrorWithError:error]);
+ });
+}
+
+- (void)authTokenWithCompletion:(FIRInstallationsTokenHandler)completion {
+ [self authTokenForcingRefresh:NO completion:completion];
+}
+
+- (void)authTokenForcingRefresh:(BOOL)forceRefresh
+ completion:(FIRInstallationsTokenHandler)completion {
+ [self.installationsIDController getAuthTokenForcingRefresh:forceRefresh]
+ .then(^FIRInstallationsAuthTokenResult *(FIRInstallationsItem *installation) {
+ FIRInstallationsAuthTokenResult *result = [[FIRInstallationsAuthTokenResult alloc]
+ initWithToken:installation.authToken.token
+ expirationDate:installation.authToken.expirationDate];
+ return result;
+ })
+ .then(^id(FIRInstallationsAuthTokenResult *token) {
+ completion(token, nil);
+ return nil;
+ })
+ .catch(^void(NSError *error) {
+ completion(nil, [FIRInstallationsErrorUtil publicDomainErrorWithError:error]);
+ });
+}
+
+- (void)deleteWithCompletion:(void (^)(NSError *__nullable error))completion {
+ [self.installationsIDController deleteInstallation]
+ .then(^id(id result) {
+ completion(nil);
+ return nil;
+ })
+ .catch(^void(NSError *error) {
+ completion([FIRInstallationsErrorUtil publicDomainErrorWithError:error]);
+ });
+}
+
+#pragma mark - IID version compatibility
+
++ (void)assertCompatibleIIDVersion {
+ // We use this flag to disable IID compatibility exception for unit tests.
+#ifdef FIR_INSTALLATIONS_ALLOWS_INCOMPATIBLE_IID_VERSION
+ return;
+#else
+ if (![self isIIDVersionCompatible]) {
+ [NSException raise:kFirebaseInstallationsErrorDomain
+ format:@"FirebaseInstallations will not work correctly with current version of "
+ @"Firebase Instance ID. Please update your Firebase Instance ID version."];
+ }
+#endif
+}
+
++ (BOOL)isIIDVersionCompatible {
+ Class IIDClass = NSClassFromString(@"FIRInstanceID");
+ if (IIDClass == nil) {
+ // It is OK if there is no IID at all.
+ return YES;
+ }
+ // We expect a compatible version having the method `+[FIRInstanceID usesFIS]` defined.
+ BOOL isCompatibleVersion = [IIDClass respondsToSelector:NSSelectorFromString(@"usesFIS")];
+ return isCompatibleVersion;
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m
new file mode 100644
index 000000000..92e5fab19
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsAuthTokenResultInternal.h"
+
+@implementation FIRInstallationsAuthTokenResult
+
+- (instancetype)initWithToken:(NSString *)token expirationDate:(NSDate *)expirationDate {
+ self = [super init];
+ if (self) {
+ _authToken = [token copy];
+ _expirationDate = expirationDate;
+ }
+ return self;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h
new file mode 100644
index 000000000..0c959dba5
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FIRInstallationsAuthTokenResult (Internal)
+
+- (instancetype)initWithToken:(NSString *)token expirationDate:(NSDate *)expirationTime;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.h
new file mode 100644
index 000000000..95fdf835f
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+#import "FIRInstallationsStatus.h"
+
+@class FIRInstallationsStoredItem;
+@class FIRInstallationsStoredAuthToken;
+@class FIRInstallationsStoredIIDCheckin;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * The class represents the required installation ID and auth token data including possible states.
+ * The data is stored to Keychain via `FIRInstallationsStoredItem` which has only the storage
+ * relevant data and does not contain any logic. `FIRInstallationsItem` must be used on the logic
+ * level (not `FIRInstallationsStoredItem`).
+ */
+@interface FIRInstallationsItem : NSObject
+
+/// A `FirebaseApp` identifier.
+@property(nonatomic, readonly) NSString *appID;
+/// A `FirebaseApp` name.
+@property(nonatomic, readonly) NSString *firebaseAppName;
+/// A stable identifier that uniquely identifies the app instance.
+@property(nonatomic, copy, nullable) NSString *firebaseInstallationID;
+/// The `refreshToken` is used to authorize the auth token requests.
+@property(nonatomic, copy, nullable) NSString *refreshToken;
+
+@property(nonatomic, nullable) FIRInstallationsStoredAuthToken *authToken;
+@property(nonatomic, assign) FIRInstallationsStatus registrationStatus;
+
+/// Instance ID default token imported from IID store as a part of IID migration.
+@property(nonatomic, nullable) NSString *IIDDefaultToken;
+
+- (instancetype)initWithAppID:(NSString *)appID firebaseAppName:(NSString *)firebaseAppName;
+
+/**
+ * Populates `FIRInstallationsItem` properties with data from `FIRInstallationsStoredItem`.
+ * @param item An instance of `FIRInstallationsStoredItem` to get data from.
+ */
+- (void)updateWithStoredItem:(FIRInstallationsStoredItem *)item;
+
+/**
+ * Creates a stored item with data from the object.
+ * @return Returns a `FIRInstallationsStoredItem` instance with the data from the object.
+ */
+- (FIRInstallationsStoredItem *)storedItem;
+
+/**
+ * The installation identifier.
+ * @return Returns a string uniquely identifying the installation.
+ */
+- (NSString *)identifier;
+
+/**
+ * The installation identifier.
+ * @param appID A `FirebaseApp` identifier.
+ * @param appName A `FirebaseApp` name.
+ * @return Returns a string uniquely identifying the installation.
+ */
++ (NSString *)identifierWithAppID:(NSString *)appID appName:(NSString *)appName;
+
+/**
+ * Generate a new Firebase Installation Identifier.
+ * @return Returns a 22 characters long globally unique string created based on UUID.
+ */
++ (NSString *)generateFID;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.m
new file mode 100644
index 000000000..bc819bf8a
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.m
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsItem.h"
+
+#import "FIRInstallationsStoredAuthToken.h"
+#import "FIRInstallationsStoredItem.h"
+
+@implementation FIRInstallationsItem
+
+- (instancetype)initWithAppID:(NSString *)appID firebaseAppName:(NSString *)firebaseAppName {
+ self = [super init];
+ if (self) {
+ _appID = [appID copy];
+ _firebaseAppName = [firebaseAppName copy];
+ }
+ return self;
+}
+
+- (nonnull id)copyWithZone:(nullable NSZone *)zone {
+ FIRInstallationsItem *clone = [[FIRInstallationsItem alloc] initWithAppID:self.appID
+ firebaseAppName:self.firebaseAppName];
+ clone.firebaseInstallationID = [self.firebaseInstallationID copy];
+ clone.refreshToken = [self.refreshToken copy];
+ clone.authToken = [self.authToken copy];
+ clone.registrationStatus = self.registrationStatus;
+
+ return clone;
+}
+
+- (void)updateWithStoredItem:(FIRInstallationsStoredItem *)item {
+ self.firebaseInstallationID = item.firebaseInstallationID;
+ self.refreshToken = item.refreshToken;
+ self.authToken = item.authToken;
+ self.registrationStatus = item.registrationStatus;
+ self.IIDDefaultToken = item.IIDDefaultToken;
+}
+
+- (FIRInstallationsStoredItem *)storedItem {
+ FIRInstallationsStoredItem *storedItem = [[FIRInstallationsStoredItem alloc] init];
+ storedItem.firebaseInstallationID = self.firebaseInstallationID;
+ storedItem.refreshToken = self.refreshToken;
+ storedItem.authToken = self.authToken;
+ storedItem.registrationStatus = self.registrationStatus;
+ storedItem.IIDDefaultToken = self.IIDDefaultToken;
+ return storedItem;
+}
+
+- (nonnull NSString *)identifier {
+ return [[self class] identifierWithAppID:self.appID appName:self.firebaseAppName];
+}
+
++ (NSString *)identifierWithAppID:(NSString *)appID appName:(NSString *)appName {
+ return [appID stringByAppendingString:appName];
+}
+
++ (NSString *)generateFID {
+ NSUUID *UUID = [NSUUID UUID];
+ uuid_t UUIDBytes;
+ [UUID getUUIDBytes:UUIDBytes];
+
+ NSUInteger UUIDLength = sizeof(uuid_t);
+ NSData *UUIDData = [NSData dataWithBytes:UUIDBytes length:UUIDLength];
+
+ uint8_t UUIDLast4Bits = UUIDBytes[UUIDLength - 1] & 0b00001111;
+
+ // FID first 4 bits must be `0111`. The last 4 UUID bits will be cut later to form a proper FID.
+ // To keep 16 random bytes we copy these last 4 UUID to the FID 1st byte after `0111` prefix.
+ uint8_t FIDPrefix = 0b01110000 | UUIDLast4Bits;
+ NSMutableData *FIDData = [NSMutableData dataWithBytes:&FIDPrefix length:1];
+
+ [FIDData appendData:UUIDData];
+ NSString *FIDString = [self base64URLEncodedStringWithData:FIDData];
+
+ // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5 bytes.
+ // Our generated ID has 16 bytes UUID + 1 byte prefix which after encoding with base64 will become
+ // 23 characters plus 1 character for "=" padding.
+
+ // Remove the 23rd character that was added because of the extra 4 bits at the
+ // end of our 17 byte data and the '=' padding.
+ return [FIDString substringWithRange:NSMakeRange(0, 22)];
+}
+
++ (NSString *)base64URLEncodedStringWithData:(NSData *)data {
+ NSString *string = [data base64EncodedStringWithOptions:0];
+ string = [string stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
+ string = [string stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
+ return string;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.h
new file mode 100644
index 000000000..baeadb2e3
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+#import
+
+extern FIRLoggerService kFIRLoggerInstallations;
+
+// FIRInstallationsAPIService.m
+extern NSString *const kFIRInstallationsMessageCodeSendAPIRequest;
+extern NSString *const kFIRInstallationsMessageCodeAPIRequestNetworkError;
+extern NSString *const kFIRInstallationsMessageCodeAPIRequestResponse;
+extern NSString *const kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse;
+extern NSString *const kFIRInstallationsMessageCodeParsingAPIResponse;
+extern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed;
+extern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed;
+extern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed;
+extern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed;
+
+// FIRInstallationsIDController.m
+extern NSString *const kFIRInstallationsMessageCodeNewGetInstallationOperationCreated;
+extern NSString *const kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated;
+extern NSString *const kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated;
+extern NSString *const kFIRInstallationsMessageCodeInvalidFirebaseConfiguration;
+
+// FIRInstallationsStoredItem.m
+extern NSString *const kFIRInstallationsMessageCodeInstallationCoderVersionMismatch;
+
+// FIRInstallationsStoredAuthToken.m
+extern NSString *const kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch;
+
+// FIRInstallationsStoredIIDCheckin.m
+extern NSString *const kFIRInstallationsMessageCodeIIDCheckinCoderVersionMismatch;
+extern NSString *const kFIRInstallationsMessageCodeIIDCheckinFailedToDecode;
+
+// FIRInstallations.m
+extern NSString *const kFIRInstallationsMessageCodeInvalidFirebaseAppOptions;
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.m
new file mode 100644
index 000000000..c2bdf37f1
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.m
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsLogger.h"
+
+FIRLoggerService kFIRLoggerInstallations = @"[Firebase/Installations]";
+
+// FIRInstallationsAPIService.m
+NSString *const kFIRInstallationsMessageCodeSendAPIRequest = @"I-FIS001001";
+NSString *const kFIRInstallationsMessageCodeAPIRequestNetworkError = @"I-FIS001002";
+NSString *const kFIRInstallationsMessageCodeAPIRequestResponse = @"I-FIS001003";
+NSString *const kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse = @"I-FIS001004";
+NSString *const kFIRInstallationsMessageCodeParsingAPIResponse = @"I-FIS001005";
+NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed = @"I-FIS001006";
+NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed = @"I-FIS001007";
+NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed = @"I-FIS001008";
+NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed = @"I-FIS001009";
+
+// FIRInstallationsIDController.m
+NSString *const kFIRInstallationsMessageCodeNewGetInstallationOperationCreated = @"I-FIS002000";
+NSString *const kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated = @"I-FIS002001";
+NSString *const kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated = @"I-FIS002002";
+NSString *const kFIRInstallationsMessageCodeInvalidFirebaseConfiguration = @"I-FIS002003";
+
+// FIRInstallationsStoredItem.m
+NSString *const kFIRInstallationsMessageCodeInstallationCoderVersionMismatch = @"I-FIS003000";
+
+// FIRInstallationsStoredAuthToken.m
+NSString *const kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch = @"I-FIS004000";
+
+// FIRInstallationsStoredIIDCheckin.m
+NSString *const kFIRInstallationsMessageCodeIIDCheckinCoderVersionMismatch = @"I-FIS007000";
+NSString *const kFIRInstallationsMessageCodeIIDCheckinFailedToDecode = @"I-FIS007001";
+
+// FIRInstallations.m
+NSString *const kFIRInstallationsMessageCodeInvalidFirebaseAppOptions = @"I-FIS008000";
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsVersion.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsVersion.m
new file mode 100644
index 000000000..a75e3f5be
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsVersion.m
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsVersion.h"
+
+// Convert the macro to a string
+#define STR(x) STR_EXPAND(x)
+#define STR_EXPAND(x) #x
+
+const char *const FIRInstallationsVersionStr = (const char *const)STR(FIRInstallations_LIB_VERSION);
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h
new file mode 100644
index 000000000..e2408caa7
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+@class FBLPromise;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/** The class encapsulates a port of a piece FirebaseInstanceID logic required to migrate IID. */
+@interface FIRInstallationsIIDStore : NSObject
+
+/**
+ * Retrieves existing IID if present.
+ * @return Returns a promise that is resolved with IID string if IID has been found or rejected with
+ * an error otherwise.
+ */
+- (FBLPromise *)existingIID;
+
+/**
+ * Deletes existing IID if present.
+ * @return Returns a promise that is resolved with `[NSNull null]` if the IID was successfully.
+ * deleted or was not found. The promise is rejected otherwise.
+ */
+- (FBLPromise *)deleteExistingIID;
+
+#if TARGET_OS_OSX
+/// If not `nil`, then only this keychain will be used to save and read data (see
+/// `kSecMatchSearchList` and `kSecUseKeychain`. It is mostly intended to be used by unit tests.
+@property(nonatomic, nullable) SecKeychainRef keychainRef;
+#endif // TARGET_OSX
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m
new file mode 100644
index 000000000..1f3a82afa
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsIIDStore.h"
+
+#if __has_include()
+#import
+#else
+#import "FBLPromises.h"
+#endif
+
+#import
+#import "FIRInstallationsErrorUtil.h"
+
+static NSString *const kFIRInstallationsIIDKeyPairPublicTagPrefix =
+ @"com.google.iid.keypair.public-";
+static NSString *const kFIRInstallationsIIDKeyPairPrivateTagPrefix =
+ @"com.google.iid.keypair.private-";
+static NSString *const kFIRInstallationsIIDCreationTimePlistKey = @"|S|cre";
+
+@implementation FIRInstallationsIIDStore
+
+- (FBLPromise *)existingIID {
+ return [FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)
+ do:^id _Nullable {
+ if (![self hasPlistIIDFlag]) {
+ return nil;
+ }
+
+ NSData *IIDPublicKeyData = [self IIDPublicKeyData];
+ return [self IIDWithPublicKeyData:IIDPublicKeyData];
+ }]
+ .validate(^BOOL(NSString *_Nullable IID) {
+ return IID.length > 0;
+ });
+}
+
+- (FBLPromise *)deleteExistingIID {
+ return [FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)
+ do:^id _Nullable {
+ NSError *error;
+ if (![self deleteIIDFlagFromPlist:&error]) {
+ return error;
+ }
+
+ if (![self deleteIID:&error]) {
+ return error;
+ }
+
+ return [NSNull null];
+ }];
+}
+
+#pragma mark - IID decoding
+
+- (NSString *)IIDWithPublicKeyData:(NSData *)publicKeyData {
+ NSData *publicKeySHA1 = [self sha1WithData:publicKeyData];
+
+ const uint8_t *bytes = publicKeySHA1.bytes;
+ NSMutableData *identityData = [NSMutableData dataWithData:publicKeySHA1];
+
+ uint8_t b0 = bytes[0];
+ // Take the first byte and make the initial four 7 by initially making the initial 4 bits 0
+ // and then adding 0x70 to it.
+ b0 = 0x70 + (0xF & b0);
+ // failsafe should give you back b0 itself
+ b0 = (b0 & 0xFF);
+ [identityData replaceBytesInRange:NSMakeRange(0, 1) withBytes:&b0];
+ NSData *data = [identityData subdataWithRange:NSMakeRange(0, 8 * sizeof(Byte))];
+ return [self base64URLEncodedStringWithData:data];
+}
+
+- (NSData *)sha1WithData:(NSData *)data {
+ unsigned char output[CC_SHA1_DIGEST_LENGTH];
+ unsigned int length = (unsigned int)[data length];
+
+ CC_SHA1(data.bytes, length, output);
+ return [NSData dataWithBytes:output length:CC_SHA1_DIGEST_LENGTH];
+}
+
+- (NSString *)base64URLEncodedStringWithData:(NSData *)data {
+ NSString *string = [data base64EncodedStringWithOptions:0];
+ string = [string stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
+ string = [string stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
+ string = [string stringByReplacingOccurrencesOfString:@"=" withString:@""];
+ return string;
+}
+
+#pragma mark - Keychain
+
+- (NSData *)IIDPublicKeyData {
+ NSString *tag = [self keychainKeyTagWithPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix];
+ NSDictionary *query = [self keyPairQueryWithTag:tag returnData:YES];
+
+ CFTypeRef keyRef = NULL;
+ OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&keyRef);
+
+ if (status != noErr) {
+ if (keyRef) {
+ CFRelease(keyRef);
+ }
+ return nil;
+ }
+
+ return (__bridge NSData *)keyRef;
+}
+
+- (BOOL)deleteIID:(NSError **)outError {
+ if (![self deleteKeychainKeyWithTagPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix
+ error:outError]) {
+ return NO;
+ }
+
+ if (![self deleteKeychainKeyWithTagPrefix:kFIRInstallationsIIDKeyPairPrivateTagPrefix
+ error:outError]) {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)deleteKeychainKeyWithTagPrefix:(NSString *)tagPrefix error:(NSError **)outError {
+ NSString *keyTag = [self keychainKeyTagWithPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix];
+ NSDictionary *keyQuery = [self keyPairQueryWithTag:keyTag returnData:NO];
+
+ OSStatus status = SecItemDelete((__bridge CFDictionaryRef)keyQuery);
+
+ // When item is not found, it should NOT be considered as an error. The operation should
+ // continue.
+ if (status != noErr && status != errSecItemNotFound) {
+ FIRInstallationsItemSetErrorToPointer(
+ [FIRInstallationsErrorUtil keychainErrorWithFunction:@"SecItemDelete" status:status],
+ outError);
+ return NO;
+ }
+
+ return YES;
+}
+
+- (NSDictionary *)keyPairQueryWithTag:(NSString *)tag returnData:(BOOL)shouldReturnData {
+ NSMutableDictionary *query = [NSMutableDictionary dictionary];
+ NSData *tagData = [tag dataUsingEncoding:NSUTF8StringEncoding];
+
+ query[(__bridge id)kSecClass] = (__bridge id)kSecClassKey;
+ query[(__bridge id)kSecAttrApplicationTag] = tagData;
+ query[(__bridge id)kSecAttrKeyType] = (__bridge id)kSecAttrKeyTypeRSA;
+ if (shouldReturnData) {
+ query[(__bridge id)kSecReturnData] = @(YES);
+ }
+
+#if TARGET_OS_OSX
+ if (self.keychainRef) {
+ query[(__bridge NSString *)kSecMatchSearchList] = @[ (__bridge id)(self.keychainRef) ];
+ }
+#endif // TARGET_OSX
+
+ return query;
+}
+
+- (NSString *)keychainKeyTagWithPrefix:(NSString *)prefix {
+ NSString *mainAppBundleID = [[NSBundle mainBundle] bundleIdentifier];
+ if (mainAppBundleID.length == 0) {
+ return nil;
+ }
+ return [NSString stringWithFormat:@"%@%@", prefix, mainAppBundleID];
+}
+
+- (NSString *)mainbundleIdentifier {
+ NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
+ if (!bundleIdentifier.length) {
+ return nil;
+ }
+ return bundleIdentifier;
+}
+
+#pragma mark - Plist
+
+- (BOOL)deleteIIDFlagFromPlist:(NSError **)outError {
+ NSString *path = [self plistPath];
+ if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
+ return YES;
+ }
+
+ NSMutableDictionary *plistContent = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
+ plistContent[kFIRInstallationsIIDCreationTimePlistKey] = nil;
+
+ if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
+ return [plistContent writeToURL:[NSURL fileURLWithPath:path] error:outError];
+ }
+
+ return [plistContent writeToFile:path atomically:YES];
+}
+
+- (BOOL)hasPlistIIDFlag {
+ NSString *path = [self plistPath];
+ if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
+ return NO;
+ }
+
+ NSDictionary *plistContent = [[NSDictionary alloc] initWithContentsOfFile:path];
+ return plistContent[kFIRInstallationsIIDCreationTimePlistKey] != nil;
+}
+
+- (NSString *)plistPath {
+ NSString *plistNameWithExtension = @"com.google.iid-keypair.plist";
+ NSString *_subDirectoryName = @"Google/FirebaseInstanceID";
+
+ NSArray *directoryPaths =
+ NSSearchPathForDirectoriesInDomains([self supportedDirectory], NSUserDomainMask, YES);
+ NSArray *components = @[ directoryPaths.lastObject, _subDirectoryName, plistNameWithExtension ];
+
+ return [NSString pathWithComponents:components];
+}
+
+- (NSSearchPathDirectory)supportedDirectory {
+#if TARGET_OS_TV
+ return NSCachesDirectory;
+#else
+ return NSApplicationSupportDirectory;
+#endif
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h
new file mode 100644
index 000000000..ed98e3d70
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+@class FBLPromise;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * The class reads a default IID token from IID store if available.
+ */
+@interface FIRInstallationsIIDTokenStore : NSObject
+
+- (instancetype)init NS_UNAVAILABLE;
+
+- (instancetype)initWithGCMSenderID:(NSString *)GCMSenderID;
+
+- (FBLPromise *)existingIIDDefaultToken;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m
new file mode 100644
index 000000000..1c9dbabeb
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsIIDTokenStore.h"
+
+#if __has_include()
+#import
+#else
+#import "FBLPromises.h"
+#endif
+
+#import "FIRInstallationsErrorUtil.h"
+#import "FIRInstallationsKeychainUtils.h"
+
+static NSString *const kFIRInstallationsIIDTokenKeychainId = @"com.google.iid-tokens";
+
+@interface FIRInstallationsIIDTokenInfo : NSObject
+@property(nonatomic, nullable, copy) NSString *token;
+@end
+
+@implementation FIRInstallationsIIDTokenInfo
+
++ (BOOL)supportsSecureCoding {
+ return YES;
+}
+
+- (void)encodeWithCoder:(nonnull NSCoder *)coder {
+}
+
+- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {
+ self = [super init];
+ if (self) {
+ _token = [coder decodeObjectOfClass:[NSString class] forKey:@"token"];
+ }
+ return self;
+}
+
+@end
+
+@interface FIRInstallationsIIDTokenStore ()
+@property(nonatomic, readonly) NSString *GCMSenderID;
+@end
+
+@implementation FIRInstallationsIIDTokenStore
+
+- (instancetype)initWithGCMSenderID:(NSString *)GCMSenderID {
+ self = [super init];
+ if (self) {
+ _GCMSenderID = GCMSenderID;
+ }
+ return self;
+}
+
+- (FBLPromise *)existingIIDDefaultToken {
+ return [[FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)
+ do:^id _Nullable {
+ return [self IIDDefaultTokenData];
+ }] onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)
+ then:^id _Nullable(NSData *_Nullable keychainData) {
+ return [self IIDCheckinWithData:keychainData];
+ }];
+}
+
+- (FBLPromise *)IIDCheckinWithData:(NSData *)data {
+ FBLPromise *resultPromise = [FBLPromise pendingPromise];
+
+ NSError *archiverError;
+ NSKeyedUnarchiver *unarchiver;
+ if (@available(iOS 11.0, tvOS 11.0, macOS 10.13, *)) {
+ unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&archiverError];
+ } else {
+ @try {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
+#pragma clang diagnostic pop
+ } @catch (NSException *exception) {
+ archiverError = [FIRInstallationsErrorUtil keyedArchiverErrorWithException:exception];
+ }
+ }
+
+ if (!unarchiver) {
+ NSError *error = archiverError ?: [FIRInstallationsErrorUtil corruptedIIDTokenData];
+ [resultPromise reject:error];
+ return resultPromise;
+ }
+
+ [unarchiver setClass:[FIRInstallationsIIDTokenInfo class] forClassName:@"FIRInstanceIDTokenInfo"];
+ FIRInstallationsIIDTokenInfo *IIDTokenInfo =
+ [unarchiver decodeObjectOfClass:[FIRInstallationsIIDTokenInfo class]
+ forKey:NSKeyedArchiveRootObjectKey];
+
+ if (IIDTokenInfo.token.length < 1) {
+ [resultPromise reject:[FIRInstallationsErrorUtil corruptedIIDTokenData]];
+ return resultPromise;
+ }
+
+ [resultPromise fulfill:IIDTokenInfo.token];
+
+ return resultPromise;
+}
+
+- (FBLPromise *)IIDDefaultTokenData {
+ FBLPromise *resultPromise = [FBLPromise pendingPromise];
+
+ NSMutableDictionary *keychainQuery = [self IIDDefaultTokenDataKeychainQuery];
+ NSError *error;
+ NSData *data = [FIRInstallationsKeychainUtils getItemWithQuery:keychainQuery error:&error];
+
+ if (data) {
+ [resultPromise fulfill:data];
+ return resultPromise;
+ } else {
+ NSError *outError = error ?: [FIRInstallationsErrorUtil corruptedIIDTokenData];
+ [resultPromise reject:outError];
+ return resultPromise;
+ }
+}
+
+- (NSMutableDictionary *)IIDDefaultTokenDataKeychainQuery {
+ NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword};
+
+ NSMutableDictionary *finalQuery = [NSMutableDictionary dictionaryWithDictionary:query];
+ finalQuery[(__bridge NSString *)kSecAttrGeneric] = kFIRInstallationsIIDTokenKeychainId;
+
+ NSString *account = [self IIDAppIdentifier];
+ if ([account length]) {
+ finalQuery[(__bridge NSString *)kSecAttrAccount] = account;
+ }
+
+ finalQuery[(__bridge NSString *)kSecAttrService] =
+ [self serviceKeyForAuthorizedEntity:self.GCMSenderID scope:@"*"];
+ return finalQuery;
+}
+
+- (NSString *)IIDAppIdentifier {
+ return [[NSBundle mainBundle] bundleIdentifier] ?: @"";
+}
+
+- (NSString *)serviceKeyForAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope {
+ return [NSString stringWithFormat:@"%@:%@", authorizedEntity, scope];
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h
new file mode 100644
index 000000000..b45475d1a
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+@class FBLPromise;
+@class FIRInstallationsItem;
+
+NS_ASSUME_NONNULL_BEGIN
+
+FOUNDATION_EXPORT NSString *const kFIRInstallationsUserAgentKey;
+
+FOUNDATION_EXPORT NSString *const kFIRInstallationsHeartbeatKey;
+
+/**
+ * The class is responsible for interacting with HTTP REST API for Installations.
+ */
+@interface FIRInstallationsAPIService : NSObject
+
+/**
+ * The default initializer.
+ * @param APIKey The Firebase project API key (see `FIROptions.APIKey`).
+ * @param projectID The Firebase project ID (see `FIROptions.projectID`).
+ */
+- (instancetype)initWithAPIKey:(NSString *)APIKey projectID:(NSString *)projectID;
+
+/**
+ * Sends a request to register a new FID to get auth and refresh tokens.
+ * @param installation The `FIRInstallationsItem` instance with the FID to register.
+ * @return A promise that is resolved with a new `FIRInstallationsItem` instance with valid tokens.
+ * It is rejected with an error in case of a failure.
+ */
+- (FBLPromise *)registerInstallation:(FIRInstallationsItem *)installation;
+
+- (FBLPromise *)refreshAuthTokenForInstallation:
+ (FIRInstallationsItem *)installation;
+
+/**
+ * Sends a request to delete the installation, related auth tokens and all related data from the
+ * server.
+ * @param installation The installation to delete.
+ * @return Returns a promise that is resolved with the passed installation on successful deletion or
+ * is rejected with an error otherwise.
+ */
+- (FBLPromise *)deleteInstallation:(FIRInstallationsItem *)installation;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m
new file mode 100644
index 000000000..5bd7e3b98
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m
@@ -0,0 +1,346 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsAPIService.h"
+
+#import
+
+#if __has_include()
+#import
+#else
+#import "FBLPromises.h"
+#endif
+
+#import
+#import
+#import "FIRInstallationsErrorUtil.h"
+#import "FIRInstallationsItem+RegisterInstallationAPI.h"
+#import "FIRInstallationsLogger.h"
+
+NSString *const kFIRInstallationsAPIBaseURL = @"https://firebaseinstallations.googleapis.com";
+NSString *const kFIRInstallationsAPIKey = @"X-Goog-Api-Key";
+NSString *const kFIRInstallationsBundleId = @"X-Ios-Bundle-Identifier";
+NSString *const kFIRInstallationsIIDMigrationAuthHeader = @"x-goog-fis-ios-iid-migration-auth";
+NSString *const kFIRInstallationsHeartbeatKey = @"X-firebase-client-log-type";
+NSString *const kFIRInstallationsHeartbeatTag = @"fire-installations";
+NSString *const kFIRInstallationsUserAgentKey = @"X-firebase-client";
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FIRInstallationsURLSessionResponse : NSObject
+@property(nonatomic) NSHTTPURLResponse *HTTPResponse;
+@property(nonatomic) NSData *data;
+
+- (instancetype)initWithResponse:(NSHTTPURLResponse *)response data:(nullable NSData *)data;
+@end
+
+@implementation FIRInstallationsURLSessionResponse
+
+- (instancetype)initWithResponse:(NSHTTPURLResponse *)response data:(nullable NSData *)data {
+ self = [super init];
+ if (self) {
+ _HTTPResponse = response;
+ _data = data ?: [NSData data];
+ }
+ return self;
+}
+
+@end
+
+@interface FIRInstallationsAPIService ()
+@property(nonatomic, readonly) NSURLSession *URLSession;
+@property(nonatomic, readonly) NSString *APIKey;
+@property(nonatomic, readonly) NSString *projectID;
+@end
+
+NS_ASSUME_NONNULL_END
+
+@implementation FIRInstallationsAPIService
+
+- (instancetype)initWithAPIKey:(NSString *)APIKey projectID:(NSString *)projectID {
+ NSURLSession *URLSession = [NSURLSession
+ sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
+ return [self initWithURLSession:URLSession APIKey:APIKey projectID:projectID];
+}
+
+/// The initializer for tests.
+- (instancetype)initWithURLSession:(NSURLSession *)URLSession
+ APIKey:(NSString *)APIKey
+ projectID:(NSString *)projectID {
+ self = [super init];
+ if (self) {
+ _URLSession = URLSession;
+ _APIKey = [APIKey copy];
+ _projectID = [projectID copy];
+ }
+ return self;
+}
+
+#pragma mark - Public
+
+- (FBLPromise *)registerInstallation:(FIRInstallationsItem *)installation {
+ NSURLRequest *request = [self registerRequestWithInstallation:installation];
+ return [self sendURLRequest:request].then(
+ ^id _Nullable(FIRInstallationsURLSessionResponse *response) {
+ return [self registeredInstallationWithInstallation:installation serverResponse:response];
+ });
+}
+
+- (FBLPromise *)refreshAuthTokenForInstallation:
+ (FIRInstallationsItem *)installation {
+ NSURLRequest *request = [self authTokenRequestWithInstallation:installation];
+ return [self sendURLRequest:request]
+ .then(^FBLPromise *(
+ FIRInstallationsURLSessionResponse *response) {
+ return [self authTokenWithServerResponse:response];
+ })
+ .then(^FIRInstallationsItem *(FIRInstallationsStoredAuthToken *authToken) {
+ FIRInstallationsItem *updatedInstallation = [installation copy];
+ updatedInstallation.authToken = authToken;
+ return updatedInstallation;
+ });
+}
+
+- (FBLPromise *)deleteInstallation:(FIRInstallationsItem *)installation {
+ NSURLRequest *request = [self deleteInstallationRequestWithInstallation:installation];
+ return [[self sendURLRequest:request]
+ then:^id _Nullable(FIRInstallationsURLSessionResponse *_Nullable value) {
+ // Return the original installation on success.
+ return installation;
+ }];
+}
+
+#pragma mark - Register Installation
+
+- (NSURLRequest *)registerRequestWithInstallation:(FIRInstallationsItem *)installation {
+ NSString *URLString = [NSString stringWithFormat:@"%@/v1/projects/%@/installations/",
+ kFIRInstallationsAPIBaseURL, self.projectID];
+ NSURL *URL = [NSURL URLWithString:URLString];
+
+ NSDictionary *bodyDict = @{
+ @"fid" : installation.firebaseInstallationID,
+ @"authVersion" : @"FIS_v2",
+ @"appId" : installation.appID,
+ @"sdkVersion" : [self SDKVersion]
+ };
+
+ NSDictionary *headers;
+ if (installation.IIDDefaultToken) {
+ headers = @{kFIRInstallationsIIDMigrationAuthHeader : installation.IIDDefaultToken};
+ }
+
+ return [self requestWithURL:URL
+ HTTPMethod:@"POST"
+ bodyDict:bodyDict
+ refreshToken:nil
+ additionalHeaders:headers];
+}
+
+- (FBLPromise *)
+ registeredInstallationWithInstallation:(FIRInstallationsItem *)installation
+ serverResponse:(FIRInstallationsURLSessionResponse *)response {
+ return [FBLPromise do:^id {
+ FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeParsingAPIResponse,
+ @"Parsing server response for %@.", response.HTTPResponse.URL);
+ NSError *error;
+ FIRInstallationsItem *registeredInstallation =
+ [installation registeredInstallationWithJSONData:response.data
+ date:[NSDate date]
+ error:&error];
+ if (registeredInstallation == nil) {
+ FIRLogDebug(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed,
+ @"Failed to parse FIRInstallationsItem: %@.", error);
+ return error;
+ }
+
+ FIRLogDebug(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed,
+ @"FIRInstallationsItem parsed successfully.");
+ return registeredInstallation;
+ }];
+}
+
+#pragma mark - Auth token
+
+- (NSURLRequest *)authTokenRequestWithInstallation:(FIRInstallationsItem *)installation {
+ NSString *URLString =
+ [NSString stringWithFormat:@"%@/v1/projects/%@/installations/%@/authTokens:generate",
+ kFIRInstallationsAPIBaseURL, self.projectID,
+ installation.firebaseInstallationID];
+ NSURL *URL = [NSURL URLWithString:URLString];
+
+ NSDictionary *bodyDict = @{@"installation" : @{@"sdkVersion" : [self SDKVersion]}};
+ return [self requestWithURL:URL
+ HTTPMethod:@"POST"
+ bodyDict:bodyDict
+ refreshToken:installation.refreshToken];
+}
+
+- (FBLPromise *)authTokenWithServerResponse:
+ (FIRInstallationsURLSessionResponse *)response {
+ return [FBLPromise do:^id {
+ FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeParsingAPIResponse,
+ @"Parsing server response for %@.", response.HTTPResponse.URL);
+ NSError *error;
+ FIRInstallationsStoredAuthToken *token =
+ [FIRInstallationsItem authTokenWithGenerateTokenAPIJSONData:response.data
+ date:[NSDate date]
+ error:&error];
+ if (token == nil) {
+ FIRLogDebug(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed,
+ @"Failed to parse FIRInstallationsStoredAuthToken: %@.", error);
+ return error;
+ }
+
+ FIRLogDebug(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed,
+ @"FIRInstallationsStoredAuthToken parsed successfully.");
+ return token;
+ }];
+}
+
+#pragma mark - Delete Installation
+
+- (NSURLRequest *)deleteInstallationRequestWithInstallation:(FIRInstallationsItem *)installation {
+ NSString *URLString = [NSString stringWithFormat:@"%@/v1/projects/%@/installations/%@/",
+ kFIRInstallationsAPIBaseURL, self.projectID,
+ installation.firebaseInstallationID];
+ NSURL *URL = [NSURL URLWithString:URLString];
+
+ return [self requestWithURL:URL
+ HTTPMethod:@"DELETE"
+ bodyDict:@{}
+ refreshToken:installation.refreshToken];
+}
+
+#pragma mark - URL Request
+- (NSURLRequest *)requestWithURL:(NSURL *)requestURL
+ HTTPMethod:(NSString *)HTTPMethod
+ bodyDict:(NSDictionary *)bodyDict
+ refreshToken:(nullable NSString *)refreshToken {
+ return [self requestWithURL:requestURL
+ HTTPMethod:HTTPMethod
+ bodyDict:bodyDict
+ refreshToken:refreshToken
+ additionalHeaders:nil];
+}
+
+- (NSURLRequest *)requestWithURL:(NSURL *)requestURL
+ HTTPMethod:(NSString *)HTTPMethod
+ bodyDict:(NSDictionary *)bodyDict
+ refreshToken:(nullable NSString *)refreshToken
+ additionalHeaders:
+ (nullable NSDictionary *)additionalHeaders {
+ __block NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL];
+ request.HTTPMethod = HTTPMethod;
+ NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
+ [request addValue:self.APIKey forHTTPHeaderField:kFIRInstallationsAPIKey];
+ [request addValue:bundleIdentifier forHTTPHeaderField:kFIRInstallationsBundleId];
+ [self setJSONHTTPBody:bodyDict forRequest:request];
+ if (refreshToken) {
+ NSString *authHeader = [NSString stringWithFormat:@"FIS_v2 %@", refreshToken];
+ [request setValue:authHeader forHTTPHeaderField:@"Authorization"];
+ }
+ // User agent Header.
+ [request setValue:[FIRApp firebaseUserAgent] forHTTPHeaderField:kFIRInstallationsUserAgentKey];
+ // Heartbeat Header.
+ [request setValue:@([FIRHeartbeatInfo heartbeatCodeForTag:kFIRInstallationsHeartbeatTag])
+ .stringValue
+ forHTTPHeaderField:kFIRInstallationsHeartbeatKey];
+ [additionalHeaders enumerateKeysAndObjectsUsingBlock:^(
+ NSString *_Nonnull key, NSString *_Nonnull obj, BOOL *_Nonnull stop) {
+ [request setValue:obj forHTTPHeaderField:key];
+ }];
+
+ return [request copy];
+}
+
+- (FBLPromise *)URLRequestPromise:(NSURLRequest *)request {
+ return [[FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {
+ FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeSendAPIRequest,
+ @"Sending request: %@, body:%@, headers: %@.", request,
+ [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding],
+ request.allHTTPHeaderFields);
+ [[self.URLSession
+ dataTaskWithRequest:request
+ completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response,
+ NSError *_Nullable error) {
+ if (error) {
+ FIRLogDebug(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeAPIRequestNetworkError,
+ @"Request failed: %@, error: %@.", request, error);
+ reject(error);
+ } else {
+ FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeAPIRequestResponse,
+ @"Request response received: %@, error: %@, body: %@.", request, error,
+ [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
+ fulfill([[FIRInstallationsURLSessionResponse alloc]
+ initWithResponse:(NSHTTPURLResponse *)response
+ data:data]);
+ }
+ }] resume];
+ }] then:^id _Nullable(FIRInstallationsURLSessionResponse *response) {
+ return [self validateHTTPResponseStatusCode:response];
+ }];
+}
+
+- (FBLPromise *)validateHTTPResponseStatusCode:
+ (FIRInstallationsURLSessionResponse *)response {
+ NSInteger statusCode = response.HTTPResponse.statusCode;
+ return [FBLPromise do:^id _Nullable {
+ if (statusCode < 200 || statusCode >= 300) {
+ FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse,
+ @"Unexpected API response: %@, body: %@.", response.HTTPResponse,
+ [[NSString alloc] initWithData:response.data encoding:NSUTF8StringEncoding]);
+ return [FIRInstallationsErrorUtil APIErrorWithHTTPResponse:response.HTTPResponse
+ data:response.data];
+ }
+ return response;
+ }];
+}
+
+- (FBLPromise *)sendURLRequest:(NSURLRequest *)request {
+ return [FBLPromise attempts:1
+ delay:1
+ condition:^BOOL(NSInteger remainingAttempts, NSError *_Nonnull error) {
+ return [FIRInstallationsErrorUtil isAPIError:error withHTTPCode:500];
+ }
+ retry:^id _Nullable {
+ return [self URLRequestPromise:request];
+ }];
+}
+
+- (NSString *)SDKVersion {
+ return [NSString stringWithFormat:@"i:%s", FIRInstallationsVersionStr];
+}
+
+#pragma mark - JSON
+
+- (void)setJSONHTTPBody:(NSDictionary *)body
+ forRequest:(NSMutableURLRequest *)request {
+ [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
+
+ NSError *error;
+ NSData *JSONData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error];
+ if (JSONData == nil) {
+ // TODO: Log or return an error.
+ }
+ request.HTTPBody = JSONData;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h
new file mode 100644
index 000000000..cc6b54320
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsItem.h"
+
+@class FIRInstallationsStoredAuthToken;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FIRInstallationsItem (RegisterInstallationAPI)
+
+/**
+ * Parses and validates the Register Installation API response and returns a corresponding
+ * `FIRInstallationsItem` instance on success.
+ * @param JSONData The data with JSON encoded API response.
+ * @param date The Auth Token expiration date will be calculated as `date` +
+ * `response.authToken.expiresIn`. For most of the cases `[NSDate date]` should be passed there. A
+ * different value may be passed e.g. for unit tests.
+ * @param outError A pointer to assign a specific `NSError` instance in case of failure. No error is
+ * assigned in case of success.
+ * @return Returns a new `FIRInstallationsItem` instance in the success case or `nil` otherwise.
+ */
+- (nullable FIRInstallationsItem *)registeredInstallationWithJSONData:(NSData *)JSONData
+ date:(NSDate *)date
+ error:
+ (NSError *_Nullable *)outError;
+
++ (nullable FIRInstallationsStoredAuthToken *)authTokenWithGenerateTokenAPIJSONData:(NSData *)data
+ date:(NSDate *)date
+ error:(NSError **)
+ outError;
+
++ (nullable FIRInstallationsStoredAuthToken *)authTokenWithJSONDict:
+ (NSDictionary *)dict
+ date:(NSDate *)date
+ error:(NSError **)outError;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m
new file mode 100644
index 000000000..569e35b99
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsItem+RegisterInstallationAPI.h"
+
+#import "FIRInstallationsErrorUtil.h"
+#import "FIRInstallationsStoredAuthToken.h"
+
+@implementation FIRInstallationsItem (RegisterInstallationAPI)
+
+- (nullable FIRInstallationsItem *)
+ registeredInstallationWithJSONData:(NSData *)data
+ date:(NSDate *)date
+ error:(NSError *__autoreleasing _Nullable *_Nullable)outError {
+ NSDictionary *responseJSON = [FIRInstallationsItem dictionaryFromJSONData:data error:outError];
+ if (!responseJSON) {
+ return nil;
+ }
+
+ NSString *refreshToken = [FIRInstallationsItem validStringOrNilForKey:@"refreshToken"
+ fromDict:responseJSON];
+ if (refreshToken == nil) {
+ FIRInstallationsItemSetErrorToPointer(
+ [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@"refreshToken"],
+ outError);
+ return nil;
+ }
+
+ NSDictionary *authTokenDict = responseJSON[@"authToken"];
+ if (![authTokenDict isKindOfClass:[NSDictionary class]]) {
+ FIRInstallationsItemSetErrorToPointer(
+ [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@"authToken"],
+ outError);
+ return nil;
+ }
+
+ FIRInstallationsStoredAuthToken *authToken =
+ [FIRInstallationsItem authTokenWithJSONDict:authTokenDict date:date error:outError];
+ if (authToken == nil) {
+ return nil;
+ }
+
+ FIRInstallationsItem *installation =
+ [[FIRInstallationsItem alloc] initWithAppID:self.appID firebaseAppName:self.firebaseAppName];
+ NSString *installationID = [FIRInstallationsItem validStringOrNilForKey:@"fid"
+ fromDict:responseJSON];
+ installation.firebaseInstallationID = installationID ?: self.firebaseInstallationID;
+ installation.refreshToken = refreshToken;
+ installation.authToken = authToken;
+ installation.registrationStatus = FIRInstallationStatusRegistered;
+
+ return installation;
+}
+
+#pragma mark - Auth token
+
++ (nullable FIRInstallationsStoredAuthToken *)authTokenWithGenerateTokenAPIJSONData:(NSData *)data
+ date:(NSDate *)date
+ error:(NSError **)
+ outError {
+ NSDictionary *dict = [self dictionaryFromJSONData:data error:outError];
+ if (!dict) {
+ return nil;
+ }
+
+ return [self authTokenWithJSONDict:dict date:date error:outError];
+}
+
++ (nullable FIRInstallationsStoredAuthToken *)authTokenWithJSONDict:
+ (NSDictionary *)dict
+ date:(NSDate *)date
+ error:(NSError **)outError {
+ NSString *token = [self validStringOrNilForKey:@"token" fromDict:dict];
+ if (token == nil) {
+ FIRInstallationsItemSetErrorToPointer(
+ [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@"authToken.token"],
+ outError);
+ return nil;
+ }
+
+ NSString *expiresInString = [self validStringOrNilForKey:@"expiresIn" fromDict:dict];
+ if (expiresInString == nil) {
+ FIRInstallationsItemSetErrorToPointer(
+ [FIRInstallationsErrorUtil
+ FIDRegistrationErrorWithResponseMissingField:@"authToken.expiresIn"],
+ outError);
+ return nil;
+ }
+
+ // The response should contain the string in format like "604800s".
+ // The server should never response with anything else except seconds.
+ // Just drop the last character and parse a number from string.
+ NSString *expiresInSeconds = [expiresInString substringToIndex:expiresInString.length - 1];
+ NSTimeInterval expiresIn = [expiresInSeconds doubleValue];
+ NSDate *expirationDate = [date dateByAddingTimeInterval:expiresIn];
+
+ FIRInstallationsStoredAuthToken *authToken = [[FIRInstallationsStoredAuthToken alloc] init];
+ authToken.status = FIRInstallationsAuthTokenStatusTokenReceived;
+ authToken.token = token;
+ authToken.expirationDate = expirationDate;
+
+ return authToken;
+}
+
+#pragma mark - JSON
+
++ (nullable NSDictionary *)dictionaryFromJSONData:(NSData *)data
+ error:(NSError **)outError {
+ NSError *error;
+ NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
+
+ if (![responseJSON isKindOfClass:[NSDictionary class]]) {
+ FIRInstallationsItemSetErrorToPointer([FIRInstallationsErrorUtil JSONSerializationError:error],
+ outError);
+ return nil;
+ }
+
+ return responseJSON;
+}
+
++ (NSString *)validStringOrNilForKey:(NSString *)key fromDict:(NSDictionary *)dict {
+ NSString *string = dict[key];
+ if ([string isKindOfClass:[NSString class]] && string.length > 0) {
+ return string;
+ }
+ return nil;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h
new file mode 100644
index 000000000..ab2092d2b
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class FBLPromise;
+@class FIRInstallationsItem;
+
+/**
+ * The class is responsible for managing FID for a given `FIRApp`.
+ */
+@interface FIRInstallationsIDController : NSObject
+
+- (instancetype)initWithGoogleAppID:(NSString *)appID
+ appName:(NSString *)appName
+ APIKey:(NSString *)APIKey
+ projectID:(NSString *)projectID
+ GCMSenderID:(NSString *)GCMSenderID
+ accessGroup:(nullable NSString *)accessGroup;
+
+- (FBLPromise *)getInstallationItem;
+
+- (FBLPromise *)getAuthTokenForcingRefresh:(BOOL)forceRefresh;
+
+- (FBLPromise *)deleteInstallation;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m
new file mode 100644
index 000000000..1982a5789
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m
@@ -0,0 +1,458 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsIDController.h"
+
+#if __has_include()
+#import
+#else
+#import "FBLPromises.h"
+#endif
+
+#import
+
+#import "FIRInstallationsAPIService.h"
+#import "FIRInstallationsErrorUtil.h"
+#import "FIRInstallationsIIDStore.h"
+#import "FIRInstallationsIIDTokenStore.h"
+#import "FIRInstallationsItem.h"
+#import "FIRInstallationsLogger.h"
+#import "FIRInstallationsSingleOperationPromiseCache.h"
+#import "FIRInstallationsStore.h"
+#import "FIRSecureStorage.h"
+
+#import "FIRInstallationsHTTPError.h"
+#import "FIRInstallationsStoredAuthToken.h"
+
+const NSNotificationName FIRInstallationIDDidChangeNotification =
+ @"FIRInstallationIDDidChangeNotification";
+NSString *const kFIRInstallationIDDidChangeNotificationAppNameKey =
+ @"FIRInstallationIDDidChangeNotification";
+
+NSTimeInterval const kFIRInstallationsTokenExpirationThreshold = 60 * 60; // 1 hour.
+
+@interface FIRInstallationsIDController ()
+@property(nonatomic, readonly) NSString *appID;
+@property(nonatomic, readonly) NSString *appName;
+
+@property(nonatomic, readonly) FIRInstallationsStore *installationsStore;
+@property(nonatomic, readonly) FIRInstallationsIIDStore *IIDStore;
+@property(nonatomic, readonly) FIRInstallationsIIDTokenStore *IIDTokenStore;
+
+@property(nonatomic, readonly) FIRInstallationsAPIService *APIService;
+
+@property(nonatomic, readonly) FIRInstallationsSingleOperationPromiseCache
+ *getInstallationPromiseCache;
+@property(nonatomic, readonly)
+ FIRInstallationsSingleOperationPromiseCache *authTokenPromiseCache;
+@property(nonatomic, readonly) FIRInstallationsSingleOperationPromiseCache
+ *authTokenForcingRefreshPromiseCache;
+@property(nonatomic, readonly)
+ FIRInstallationsSingleOperationPromiseCache *deleteInstallationPromiseCache;
+@end
+
+@implementation FIRInstallationsIDController
+
+- (instancetype)initWithGoogleAppID:(NSString *)appID
+ appName:(NSString *)appName
+ APIKey:(NSString *)APIKey
+ projectID:(NSString *)projectID
+ GCMSenderID:(NSString *)GCMSenderID
+ accessGroup:(NSString *)accessGroup {
+ FIRSecureStorage *secureStorage = [[FIRSecureStorage alloc] init];
+ FIRInstallationsStore *installationsStore =
+ [[FIRInstallationsStore alloc] initWithSecureStorage:secureStorage accessGroup:accessGroup];
+
+ // Use `GCMSenderID` as project identifier when `projectID` is not available.
+ NSString *APIServiceProjectID = (projectID.length > 0) ? projectID : GCMSenderID;
+ FIRInstallationsAPIService *apiService =
+ [[FIRInstallationsAPIService alloc] initWithAPIKey:APIKey projectID:APIServiceProjectID];
+
+ FIRInstallationsIIDStore *IIDStore = [[FIRInstallationsIIDStore alloc] init];
+ FIRInstallationsIIDTokenStore *IIDCheckingStore =
+ [[FIRInstallationsIIDTokenStore alloc] initWithGCMSenderID:GCMSenderID];
+
+ return [self initWithGoogleAppID:appID
+ appName:appName
+ installationsStore:installationsStore
+ APIService:apiService
+ IIDStore:IIDStore
+ IIDTokenStore:IIDCheckingStore];
+}
+
+/// The initializer is supposed to be used by tests to inject `installationsStore`.
+- (instancetype)initWithGoogleAppID:(NSString *)appID
+ appName:(NSString *)appName
+ installationsStore:(FIRInstallationsStore *)installationsStore
+ APIService:(FIRInstallationsAPIService *)APIService
+ IIDStore:(FIRInstallationsIIDStore *)IIDStore
+ IIDTokenStore:(FIRInstallationsIIDTokenStore *)IIDTokenStore {
+ self = [super init];
+ if (self) {
+ _appID = appID;
+ _appName = appName;
+ _installationsStore = installationsStore;
+ _APIService = APIService;
+ _IIDStore = IIDStore;
+ _IIDTokenStore = IIDTokenStore;
+
+ __weak FIRInstallationsIDController *weakSelf = self;
+
+ _getInstallationPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc]
+ initWithNewOperationHandler:^FBLPromise *_Nonnull {
+ FIRInstallationsIDController *strongSelf = weakSelf;
+ return [strongSelf createGetInstallationItemPromise];
+ }];
+
+ _authTokenPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc]
+ initWithNewOperationHandler:^FBLPromise *_Nonnull {
+ FIRInstallationsIDController *strongSelf = weakSelf;
+ return [strongSelf installationWithValidAuthTokenForcingRefresh:NO];
+ }];
+
+ _authTokenForcingRefreshPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc]
+ initWithNewOperationHandler:^FBLPromise *_Nonnull {
+ FIRInstallationsIDController *strongSelf = weakSelf;
+ return [strongSelf installationWithValidAuthTokenForcingRefresh:YES];
+ }];
+
+ _deleteInstallationPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc]
+ initWithNewOperationHandler:^FBLPromise *_Nonnull {
+ FIRInstallationsIDController *strongSelf = weakSelf;
+ return [strongSelf createDeleteInstallationPromise];
+ }];
+ }
+ return self;
+}
+
+#pragma mark - Get Installation.
+
+- (FBLPromise *)getInstallationItem {
+ return [self.getInstallationPromiseCache getExistingPendingOrCreateNewPromise];
+}
+
+- (FBLPromise *)createGetInstallationItemPromise {
+ FIRLogDebug(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeNewGetInstallationOperationCreated, @"%s, appName: %@",
+ __PRETTY_FUNCTION__, self.appName);
+
+ FBLPromise *installationItemPromise =
+ [self getStoredInstallation].recover(^id(NSError *error) {
+ return [self createAndSaveFID];
+ });
+
+ // Initiate registration process on success if needed, but return the installation without waiting
+ // for it.
+ installationItemPromise.then(^id(FIRInstallationsItem *installation) {
+ [self getAuthTokenForcingRefresh:NO];
+ return nil;
+ });
+
+ return installationItemPromise;
+}
+
+- (FBLPromise *)getStoredInstallation {
+ return [self.installationsStore installationForAppID:self.appID appName:self.appName].validate(
+ ^BOOL(FIRInstallationsItem *installation) {
+ BOOL isValid = NO;
+ switch (installation.registrationStatus) {
+ case FIRInstallationStatusUnregistered:
+ case FIRInstallationStatusRegistered:
+ isValid = YES;
+ break;
+
+ case FIRInstallationStatusUnknown:
+ isValid = NO;
+ break;
+ }
+
+ return isValid;
+ });
+}
+
+- (FBLPromise *)createAndSaveFID {
+ return [self migrateOrGenerateInstallation]
+ .then(^FBLPromise *(FIRInstallationsItem *installation) {
+ return [self saveInstallation:installation];
+ })
+ .then(^FIRInstallationsItem *(FIRInstallationsItem *installation) {
+ [self postFIDDidChangeNotification];
+ return installation;
+ });
+}
+
+- (FBLPromise *)saveInstallation:(FIRInstallationsItem *)installation {
+ return [self.installationsStore saveInstallation:installation].then(
+ ^FIRInstallationsItem *(NSNull *result) {
+ return installation;
+ });
+}
+
+/**
+ * Tries to migrate IID data stored by FirebaseInstanceID SDK or generates a new Installation ID if
+ * not found.
+ */
+- (FBLPromise *)migrateOrGenerateInstallation {
+ if (![self isDefaultApp]) {
+ // Existing IID should be used only for default FirebaseApp.
+ FIRInstallationsItem *installation =
+ [self createInstallationWithFID:[FIRInstallationsItem generateFID] IIDDefaultToken:nil];
+ return [FBLPromise resolvedWith:installation];
+ }
+
+ return [[[FBLPromise
+ all:@[ [self.IIDStore existingIID], [self.IIDTokenStore existingIIDDefaultToken] ]]
+ then:^id _Nullable(NSArray *_Nullable results) {
+ NSString *existingIID = results[0];
+ NSString *IIDDefaultToken = results[1];
+
+ return [self createInstallationWithFID:existingIID IIDDefaultToken:IIDDefaultToken];
+ }] recover:^id _Nullable(NSError *_Nonnull error) {
+ return [self createInstallationWithFID:[FIRInstallationsItem generateFID] IIDDefaultToken:nil];
+ }];
+}
+
+- (FIRInstallationsItem *)createInstallationWithFID:(NSString *)FID
+ IIDDefaultToken:(nullable NSString *)IIDDefaultToken {
+ FIRInstallationsItem *installation = [[FIRInstallationsItem alloc] initWithAppID:self.appID
+ firebaseAppName:self.appName];
+ installation.firebaseInstallationID = FID;
+ installation.IIDDefaultToken = IIDDefaultToken;
+ installation.registrationStatus = FIRInstallationStatusUnregistered;
+ return installation;
+}
+
+#pragma mark - FID registration
+
+- (FBLPromise *)registerInstallationIfNeeded:
+ (FIRInstallationsItem *)installation {
+ switch (installation.registrationStatus) {
+ case FIRInstallationStatusRegistered:
+ // Already registered. Do nothing.
+ return [FBLPromise resolvedWith:installation];
+
+ case FIRInstallationStatusUnknown:
+ case FIRInstallationStatusUnregistered:
+ // Registration required. Proceed.
+ break;
+ }
+
+ return [self.APIService registerInstallation:installation]
+ .catch(^(NSError *_Nonnull error) {
+ if ([self doesRegistrationErrorRequireConfigChange:error]) {
+ FIRLogError(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeInvalidFirebaseConfiguration,
+ @"Firebase Installation registration failed for app with name: %@, error: "
+ @"%@\nPlease make sure you use valid GoogleService-Info.plist",
+ self.appName, error);
+ }
+ })
+ .then(^id(FIRInstallationsItem *registeredInstallation) {
+ return [self saveInstallation:registeredInstallation];
+ })
+ .then(^FIRInstallationsItem *(FIRInstallationsItem *registeredInstallation) {
+ // Server may respond with a different FID if the sent one cannot be accepted.
+ if (![registeredInstallation.firebaseInstallationID
+ isEqualToString:installation.firebaseInstallationID]) {
+ [self postFIDDidChangeNotification];
+ }
+ return registeredInstallation;
+ });
+}
+
+- (BOOL)doesRegistrationErrorRequireConfigChange:(NSError *)error {
+ FIRInstallationsHTTPError *HTTPError = (FIRInstallationsHTTPError *)error;
+ if (![HTTPError isKindOfClass:[FIRInstallationsHTTPError class]]) {
+ return NO;
+ }
+
+ switch (HTTPError.HTTPResponse.statusCode) {
+ // These are the errors that require Firebase configuration change.
+ case FIRInstallationsRegistrationHTTPCodeInvalidArgument:
+ case FIRInstallationsRegistrationHTTPCodeInvalidAPIKey:
+ case FIRInstallationsRegistrationHTTPCodeAPIKeyToProjectIDMismatch:
+ case FIRInstallationsRegistrationHTTPCodeProjectNotFound:
+ return YES;
+
+ default:
+ return NO;
+ }
+}
+
+#pragma mark - Auth Token
+
+- (FBLPromise *)getAuthTokenForcingRefresh:(BOOL)forceRefresh {
+ if (forceRefresh || [self.authTokenForcingRefreshPromiseCache getExistingPendingPromise] != nil) {
+ return [self.authTokenForcingRefreshPromiseCache getExistingPendingOrCreateNewPromise];
+ } else {
+ return [self.authTokenPromiseCache getExistingPendingOrCreateNewPromise];
+ }
+}
+
+- (FBLPromise *)installationWithValidAuthTokenForcingRefresh:
+ (BOOL)forceRefresh {
+ FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated,
+ @"-[FIRInstallationsIDController installationWithValidAuthTokenForcingRefresh:%@], "
+ @"appName: %@",
+ @(forceRefresh), self.appName);
+
+ return [self getInstallationItem]
+ .then(^FBLPromise *(FIRInstallationsItem *installation) {
+ return [self registerInstallationIfNeeded:installation];
+ })
+ .then(^id(FIRInstallationsItem *registeredInstallation) {
+ BOOL isTokenExpiredOrExpiresSoon =
+ [registeredInstallation.authToken.expirationDate timeIntervalSinceDate:[NSDate date]] <
+ kFIRInstallationsTokenExpirationThreshold;
+ if (forceRefresh || isTokenExpiredOrExpiresSoon) {
+ return [self refreshAuthTokenForInstallation:registeredInstallation];
+ } else {
+ return registeredInstallation;
+ }
+ })
+ .recover(^id(NSError *error) {
+ return [self regenerateFIDOnRefreshTokenErrorIfNeeded:error];
+ });
+}
+
+- (FBLPromise *)refreshAuthTokenForInstallation:
+ (FIRInstallationsItem *)installation {
+ return [[self.APIService refreshAuthTokenForInstallation:installation]
+ then:^id _Nullable(FIRInstallationsItem *_Nullable refreshedInstallation) {
+ return [self saveInstallation:refreshedInstallation];
+ }];
+}
+
+- (id)regenerateFIDOnRefreshTokenErrorIfNeeded:(NSError *)error {
+ if (![error isKindOfClass:[FIRInstallationsHTTPError class]]) {
+ // No recovery possible. Return the same error.
+ return error;
+ }
+
+ FIRInstallationsHTTPError *HTTPError = (FIRInstallationsHTTPError *)error;
+ switch (HTTPError.HTTPResponse.statusCode) {
+ case FIRInstallationsAuthTokenHTTPCodeInvalidAuthentication:
+ case FIRInstallationsAuthTokenHTTPCodeFIDNotFound:
+ // The stored installation was damaged or blocked by the server.
+ // Delete the stored installation then generate and register a new one.
+ return [self getInstallationItem]
+ .then(^FBLPromise *(FIRInstallationsItem *installation) {
+ return [self deleteInstallationLocally:installation];
+ })
+ .then(^FBLPromise *(id result) {
+ return [self installationWithValidAuthTokenForcingRefresh:NO];
+ });
+
+ default:
+ // No recovery possible. Return the same error.
+ return error;
+ }
+}
+
+#pragma mark - Delete FID
+
+- (FBLPromise *)deleteInstallation {
+ return [self.deleteInstallationPromiseCache getExistingPendingOrCreateNewPromise];
+}
+
+- (FBLPromise *)createDeleteInstallationPromise {
+ FIRLogDebug(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated, @"%s, appName: %@",
+ __PRETTY_FUNCTION__, self.appName);
+
+ // Check for ongoing requests first, if there is no a request, then check local storage for
+ // existing installation.
+ FBLPromise *currentInstallationPromise =
+ [self mostRecentInstallationOperation] ?: [self getStoredInstallation];
+
+ return currentInstallationPromise
+ .then(^id(FIRInstallationsItem *installation) {
+ return [self sendDeleteInstallationRequestIfNeeded:installation];
+ })
+ .then(^id(FIRInstallationsItem *installation) {
+ // Remove the installation from the local storage.
+ return [self deleteInstallationLocally:installation];
+ });
+}
+
+- (FBLPromise *)deleteInstallationLocally:(FIRInstallationsItem *)installation {
+ return [self.installationsStore removeInstallationForAppID:installation.appID
+ appName:installation.firebaseAppName]
+ .then(^FBLPromise *(NSNull *result) {
+ return [self deleteExistingIIDIfNeeded];
+ })
+ .then(^NSNull *(NSNull *result) {
+ [self postFIDDidChangeNotification];
+ return result;
+ });
+}
+
+- (FBLPromise *)sendDeleteInstallationRequestIfNeeded:
+ (FIRInstallationsItem *)installation {
+ switch (installation.registrationStatus) {
+ case FIRInstallationStatusUnknown:
+ case FIRInstallationStatusUnregistered:
+ // The installation is not registered, so it is safe to be deleted as is, so return early.
+ return [FBLPromise resolvedWith:installation];
+ break;
+
+ case FIRInstallationStatusRegistered:
+ // Proceed to de-register the installation on the server.
+ break;
+ }
+
+ return [self.APIService deleteInstallation:installation].recover(^id(NSError *APIError) {
+ if ([FIRInstallationsErrorUtil isAPIError:APIError withHTTPCode:404]) {
+ // The installation was not found on the server.
+ // Return success.
+ return installation;
+ } else {
+ // Re-throw the error otherwise.
+ return APIError;
+ }
+ });
+}
+
+- (FBLPromise *)deleteExistingIIDIfNeeded {
+ if ([self isDefaultApp]) {
+ return [self.IIDStore deleteExistingIID];
+ } else {
+ return [FBLPromise resolvedWith:[NSNull null]];
+ }
+}
+
+- (nullable FBLPromise *)mostRecentInstallationOperation {
+ return [self.authTokenForcingRefreshPromiseCache getExistingPendingPromise]
+ ?: [self.authTokenPromiseCache getExistingPendingPromise]
+ ?: [self.getInstallationPromiseCache getExistingPendingPromise];
+}
+
+#pragma mark - Notifications
+
+- (void)postFIDDidChangeNotification {
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:FIRInstallationIDDidChangeNotification
+ object:nil
+ userInfo:@{kFIRInstallationIDDidChangeNotificationAppNameKey : self.appName}];
+}
+
+#pragma mark - Default App
+
+- (BOOL)isDefaultApp {
+ return [self.appName isEqualToString:kFIRDefaultAppName];
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h
new file mode 100644
index 000000000..aeb54e504
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+@class FBLPromise;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * The class makes sure the a single operation (represented by a promise) is performed at a time. If
+ * there is an ongoing operation, then its existing corresponding promise will be returned instead
+ * of starting a new operation.
+ */
+@interface FIRInstallationsSingleOperationPromiseCache<__covariant ResultType> : NSObject
+
+- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ * The designated initializer.
+ * @param newOperationHandler The block that must return a new promise representing the
+ * single-at-a-time operation. The promise should be fulfilled when the operation is completed. The
+ * factory block will be used to create a new promise when needed.
+ */
+- (instancetype)initWithNewOperationHandler:
+ (FBLPromise *_Nonnull (^)(void))newOperationHandler NS_DESIGNATED_INITIALIZER;
+
+/**
+ * Creates a new promise or returns an existing pending one.
+ * @return Returns and existing pending promise if exists. If the pending promise does not exist
+ * then a new one will be created using the `factory` block passed in the initializer. Once the
+ * pending promise gets resolved, it is removed, so calling the method again will lead to creating
+ * and caching another promise.
+ */
+- (FBLPromise *)getExistingPendingOrCreateNewPromise;
+
+/**
+ * Returns an existing pending promise or `nil`.
+ * @return Returns an existing pending promise if there is one or `nil` otherwise.
+ */
+- (nullable FBLPromise *)getExistingPendingPromise;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m
new file mode 100644
index 000000000..dfccfe36d
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsSingleOperationPromiseCache.h"
+
+#if __has_include()
+#import
+#else
+#import "FBLPromises.h"
+#endif
+
+@interface FIRInstallationsSingleOperationPromiseCache ()
+@property(nonatomic, readonly) FBLPromise *_Nonnull (^newOperationHandler)(void);
+@property(nonatomic, nullable) FBLPromise *pendingPromise;
+@end
+
+@implementation FIRInstallationsSingleOperationPromiseCache
+
+- (instancetype)initWithNewOperationHandler:
+ (FBLPromise *_Nonnull (^)(void))newOperationHandler {
+ if (newOperationHandler == nil) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"`newOperationHandler` must not be `nil`."];
+ }
+
+ self = [super init];
+ if (self) {
+ _newOperationHandler = [newOperationHandler copy];
+ }
+ return self;
+}
+
+- (FBLPromise *)getExistingPendingOrCreateNewPromise {
+ @synchronized(self) {
+ if (!self.pendingPromise) {
+ self.pendingPromise = self.newOperationHandler();
+
+ self.pendingPromise
+ .then(^id(id result) {
+ @synchronized(self) {
+ self.pendingPromise = nil;
+ return nil;
+ }
+ })
+ .catch(^void(NSError *error) {
+ @synchronized(self) {
+ self.pendingPromise = nil;
+ }
+ });
+ }
+
+ return self.pendingPromise;
+ }
+}
+
+- (nullable FBLPromise *)getExistingPendingPromise {
+ @synchronized(self) {
+ return self.pendingPromise;
+ }
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h
new file mode 100644
index 000000000..3edc69201
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+/**
+ * The enum represent possible states of the installation ID.
+ *
+ * WARNING: The enum is stored to Keychain as a part of `FIRInstallationsStoredItem`. Modification
+ * of it can lead to incompatibility with previous version. Any modification must be evaluated and,
+ * if it is really needed, the `storageVersion` must be bumped and proper migration code added.
+ */
+typedef NS_ENUM(NSInteger, FIRInstallationsStatus) {
+ /** Represents either an initial status when a FIRInstallationsItem instance was created but not
+ * stored to Keychain or an undefined status (e.g. when the status failed to deserialize).
+ */
+ FIRInstallationStatusUnknown,
+ /// The Firebase Installation has not yet been registered with FIS.
+ FIRInstallationStatusUnregistered,
+ /// The Firebase Installation has successfully been registered with FIS.
+ FIRInstallationStatusRegistered,
+};
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h
new file mode 100644
index 000000000..5334cc98b
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+@class FBLPromise;
+@class FIRInstallationsItem;
+@class FIRSecureStorage;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// The user defaults suite name used to store data.
+extern NSString *const kFIRInstallationsStoreUserDefaultsID;
+
+/// The class is responsible for storing and accessing the installations data.
+@interface FIRInstallationsStore : NSObject
+
+/**
+ * The default initializer.
+ * @param storage The secure storage to save installations data.
+ * @param accessGroup The Keychain Access Group to store and request the installations data.
+ */
+- (instancetype)initWithSecureStorage:(FIRSecureStorage *)storage
+ accessGroup:(nullable NSString *)accessGroup;
+
+/**
+ * Retrieves existing installation ID if there is.
+ * @param appID The Firebase(Google) Application ID.
+ * @param appName The Firebase Application Name.
+ *
+ * @return Returns a `FBLPromise` instance. The promise is resolved with a FIRInstallationsItem
+ * instance if there is a valid installation stored for `appID` and `appName`. The promise is
+ * rejected with a specific error when the installation has not been found or with another possible
+ * error.
+ */
+- (FBLPromise *)installationForAppID:(NSString *)appID
+ appName:(NSString *)appName;
+
+/**
+ * Saves the given installation.
+ *
+ * @param installationItem The installation data.
+ * @return Returns a promise that is resolved with `[NSNull null]` on success.
+ */
+- (FBLPromise *)saveInstallation:(FIRInstallationsItem *)installationItem;
+
+/**
+ * Removes installation data for the given app parameters.
+ * @param appID The Firebase(Google) Application ID.
+ * @param appName The Firebase Application Name.
+ *
+ * @return Returns a promise that is resolved with `[NSNull null]` on success.
+ */
+- (FBLPromise *)removeInstallationForAppID:(NSString *)appID appName:(NSString *)appName;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m
new file mode 100644
index 000000000..9fcfd7488
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsStore.h"
+
+#import
+
+#if __has_include()
+#import
+#else
+#import "FBLPromises.h"
+#endif
+
+#import "FIRInstallationsErrorUtil.h"
+#import "FIRInstallationsItem.h"
+#import "FIRInstallationsStoredItem.h"
+#import "FIRSecureStorage.h"
+
+NSString *const kFIRInstallationsStoreUserDefaultsID = @"com.firebase.FIRInstallations";
+
+@interface FIRInstallationsStore ()
+@property(nonatomic, readonly) FIRSecureStorage *secureStorage;
+@property(nonatomic, readonly, nullable) NSString *accessGroup;
+@property(nonatomic, readonly) dispatch_queue_t queue;
+@property(nonatomic, readonly) GULUserDefaults *userDefaults;
+@end
+
+@implementation FIRInstallationsStore
+
+- (instancetype)initWithSecureStorage:(FIRSecureStorage *)storage
+ accessGroup:(NSString *)accessGroup {
+ self = [super init];
+ if (self) {
+ _secureStorage = storage;
+ _accessGroup = [accessGroup copy];
+ _queue = dispatch_queue_create("com.firebase.FIRInstallationsStore", DISPATCH_QUEUE_SERIAL);
+
+ NSString *userDefaultsSuiteName = _accessGroup ?: kFIRInstallationsStoreUserDefaultsID;
+ _userDefaults = [[GULUserDefaults alloc] initWithSuiteName:userDefaultsSuiteName];
+ }
+ return self;
+}
+
+- (FBLPromise *)installationForAppID:(NSString *)appID
+ appName:(NSString *)appName {
+ NSString *itemID = [FIRInstallationsItem identifierWithAppID:appID appName:appName];
+ return [self installationExistsForAppID:appID appName:appName]
+ .then(^id(id result) {
+ return [self.secureStorage getObjectForKey:itemID
+ objectClass:[FIRInstallationsStoredItem class]
+ accessGroup:self.accessGroup];
+ })
+ .then(^id(FIRInstallationsStoredItem *_Nullable storedItem) {
+ if (storedItem == nil) {
+ return [FIRInstallationsErrorUtil installationItemNotFoundForAppID:appID appName:appName];
+ }
+
+ FIRInstallationsItem *item = [[FIRInstallationsItem alloc] initWithAppID:appID
+ firebaseAppName:appName];
+ [item updateWithStoredItem:storedItem];
+ return item;
+ });
+}
+
+- (FBLPromise *)saveInstallation:(FIRInstallationsItem *)installationItem {
+ FIRInstallationsStoredItem *storedItem = [installationItem storedItem];
+ NSString *identifier = [installationItem identifier];
+
+ return
+ [self.secureStorage setObject:storedItem forKey:identifier accessGroup:self.accessGroup].then(
+ ^id(id result) {
+ return [self setInstallationExists:YES forItemWithIdentifier:identifier];
+ });
+}
+
+- (FBLPromise *)removeInstallationForAppID:(NSString *)appID appName:(NSString *)appName {
+ NSString *identifier = [FIRInstallationsItem identifierWithAppID:appID appName:appName];
+ return [self.secureStorage removeObjectForKey:identifier accessGroup:self.accessGroup].then(
+ ^id(id result) {
+ return [self setInstallationExists:NO forItemWithIdentifier:identifier];
+ });
+}
+
+#pragma mark - User defaults
+
+- (FBLPromise *)installationExistsForAppID:(NSString *)appID appName:(NSString *)appName {
+ NSString *identifier = [FIRInstallationsItem identifierWithAppID:appID appName:appName];
+ return [FBLPromise onQueue:self.queue
+ do:^id _Nullable {
+ return [[self userDefaults] objectForKey:identifier] != nil
+ ? [NSNull null]
+ : [FIRInstallationsErrorUtil
+ installationItemNotFoundForAppID:appID
+ appName:appName];
+ }];
+}
+
+- (FBLPromise *)setInstallationExists:(BOOL)exists
+ forItemWithIdentifier:(NSString *)identifier {
+ return [FBLPromise onQueue:self.queue
+ do:^id _Nullable {
+ if (exists) {
+ [[self userDefaults] setBool:YES forKey:identifier];
+ } else {
+ [[self userDefaults] removeObjectForKey:identifier];
+ }
+
+ return [NSNull null];
+ }];
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h
new file mode 100644
index 000000000..f6e428288
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * The enum represent possible states of the installation auth token.
+ *
+ * WARNING: The enum is stored to Keychain as a part of `FIRInstallationsStoredAuthToken`.
+ * Modification of it can lead to incompatibility with previous version. Any modification must be
+ * evaluated and, if it is really needed, the `storageVersion` must be bumped and proper migration
+ * code added.
+ */
+typedef NS_ENUM(NSInteger, FIRInstallationsAuthTokenStatus) {
+ /// An initial status or an undefined value.
+ FIRInstallationsAuthTokenStatusUnknown,
+ /// The auth token has been received from the server.
+ FIRInstallationsAuthTokenStatusTokenReceived
+};
+
+/**
+ * This class serializes and deserializes the installation data into/from `NSData` to be stored in
+ * Keychain. This class is primarily used by `FIRInstallationsStore`. It is also used on the logic
+ * level as a data object (see `FIRInstallationsItem.authToken`).
+ *
+ * WARNING: Modification of the class properties can lead to incompatibility with the stored data
+ * encoded by the previous class versions. Any modification must be evaluated and, if it is really
+ * needed, the `storageVersion` must be bumped and proper migration code added.
+ */
+@interface FIRInstallationsStoredAuthToken : NSObject
+@property FIRInstallationsAuthTokenStatus status;
+
+/// The token that can be used to authorize requests to Firebase backend.
+@property(nullable, copy) NSString *token;
+/// The date when the auth token expires.
+@property(nullable, copy) NSDate *expirationDate;
+
+/// The version of local storage.
+@property(nonatomic, readonly) NSInteger storageVersion;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m
new file mode 100644
index 000000000..b21f6dd23
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsStoredAuthToken.h"
+
+#import "FIRInstallationsLogger.h"
+
+NSString *const kFIRInstallationsStoredAuthTokenStatusKey = @"status";
+NSString *const kFIRInstallationsStoredAuthTokenTokenKey = @"token";
+NSString *const kFIRInstallationsStoredAuthTokenExpirationDateKey = @"expirationDate";
+NSString *const kFIRInstallationsStoredAuthTokenStorageVersionKey = @"storageVersion";
+
+NSInteger const kFIRInstallationsStoredAuthTokenStorageVersion = 1;
+
+@implementation FIRInstallationsStoredAuthToken
+
+- (NSInteger)storageVersion {
+ return kFIRInstallationsStoredAuthTokenStorageVersion;
+}
+
+- (nonnull id)copyWithZone:(nullable NSZone *)zone {
+ FIRInstallationsStoredAuthToken *clone = [[FIRInstallationsStoredAuthToken alloc] init];
+ clone.status = self.status;
+ clone.token = [self.token copy];
+ clone.expirationDate = self.expirationDate;
+ return clone;
+}
+
+- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
+ [aCoder encodeInteger:self.status forKey:kFIRInstallationsStoredAuthTokenStatusKey];
+ [aCoder encodeObject:self.token forKey:kFIRInstallationsStoredAuthTokenTokenKey];
+ [aCoder encodeObject:self.expirationDate
+ forKey:kFIRInstallationsStoredAuthTokenExpirationDateKey];
+ [aCoder encodeInteger:self.storageVersion
+ forKey:kFIRInstallationsStoredAuthTokenStorageVersionKey];
+}
+
+- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
+ NSInteger storageVersion =
+ [aDecoder decodeIntegerForKey:kFIRInstallationsStoredAuthTokenStorageVersionKey];
+ if (storageVersion > kFIRInstallationsStoredAuthTokenStorageVersion) {
+ FIRLogWarning(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch,
+ @"FIRInstallationsStoredAuthToken was encoded by a newer coder version %ld. "
+ @"Current coder version is %ld. Some auth token data may be lost.",
+ (long)storageVersion, (long)kFIRInstallationsStoredAuthTokenStorageVersion);
+ }
+
+ FIRInstallationsStoredAuthToken *object = [[FIRInstallationsStoredAuthToken alloc] init];
+ object.status = [aDecoder decodeIntegerForKey:kFIRInstallationsStoredAuthTokenStatusKey];
+ object.token = [aDecoder decodeObjectOfClass:[NSString class]
+ forKey:kFIRInstallationsStoredAuthTokenTokenKey];
+ object.expirationDate =
+ [aDecoder decodeObjectOfClass:[NSDate class]
+ forKey:kFIRInstallationsStoredAuthTokenExpirationDateKey];
+
+ return object;
+}
+
++ (BOOL)supportsSecureCoding {
+ return YES;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h
new file mode 100644
index 000000000..4926588c2
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+#import "FIRInstallationsStatus.h"
+
+@class FIRInstallationsStoredAuthToken;
+@class FIRInstallationsStoredIIDCheckin;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * The class is supposed to be used by `FIRInstallationsStore` only. It is required to
+ * serialize/deserialize the installation data into/from `NSData` to be stored in Keychain.
+ *
+ * WARNING: Modification of the class properties can lead to incompatibility with the stored data
+ * encoded by the previous class versions. Any modification must be evaluated and, if it is really
+ * needed, the `storageVersion` must be bumped and proper migration code added.
+ */
+@interface FIRInstallationsStoredItem : NSObject
+
+/// A stable identifier that uniquely identifies the app instance.
+@property(nonatomic, copy, nullable) NSString *firebaseInstallationID;
+/// The `refreshToken` is used to authorize the auth token requests.
+@property(nonatomic, copy, nullable) NSString *refreshToken;
+
+@property(nonatomic, nullable) FIRInstallationsStoredAuthToken *authToken;
+@property(nonatomic) FIRInstallationsStatus registrationStatus;
+
+/// Instance ID default auth token imported from IID store as a part of IID migration.
+@property(nonatomic, nullable) NSString *IIDDefaultToken;
+
+/// The version of local storage.
+@property(nonatomic, readonly) NSInteger storageVersion;
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m
new file mode 100644
index 000000000..0c7655c39
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsStoredItem.h"
+
+#import "FIRInstallationsLogger.h"
+#import "FIRInstallationsStoredAuthToken.h"
+
+NSString *const kFIRInstallationsStoredItemFirebaseInstallationIDKey = @"firebaseInstallationID";
+NSString *const kFIRInstallationsStoredItemRefreshTokenKey = @"refreshToken";
+NSString *const kFIRInstallationsStoredItemAuthTokenKey = @"authToken";
+NSString *const kFIRInstallationsStoredItemRegistrationStatusKey = @"registrationStatus";
+NSString *const kFIRInstallationsStoredItemIIDDefaultTokenKey = @"IIDDefaultToken";
+NSString *const kFIRInstallationsStoredItemStorageVersionKey = @"storageVersion";
+
+NSInteger const kFIRInstallationsStoredItemStorageVersion = 1;
+
+@implementation FIRInstallationsStoredItem
+
+- (NSInteger)storageVersion {
+ return kFIRInstallationsStoredItemStorageVersion;
+}
+
+- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
+ [aCoder encodeObject:self.firebaseInstallationID
+ forKey:kFIRInstallationsStoredItemFirebaseInstallationIDKey];
+ [aCoder encodeObject:self.refreshToken forKey:kFIRInstallationsStoredItemRefreshTokenKey];
+ [aCoder encodeObject:self.authToken forKey:kFIRInstallationsStoredItemAuthTokenKey];
+ [aCoder encodeInteger:self.registrationStatus
+ forKey:kFIRInstallationsStoredItemRegistrationStatusKey];
+ [aCoder encodeObject:self.IIDDefaultToken forKey:kFIRInstallationsStoredItemIIDDefaultTokenKey];
+ [aCoder encodeInteger:self.storageVersion forKey:kFIRInstallationsStoredItemStorageVersionKey];
+}
+
+- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
+ NSInteger storageVersion =
+ [aDecoder decodeIntegerForKey:kFIRInstallationsStoredItemStorageVersionKey];
+ if (storageVersion > self.storageVersion) {
+ FIRLogWarning(kFIRLoggerInstallations,
+ kFIRInstallationsMessageCodeInstallationCoderVersionMismatch,
+ @"FIRInstallationsStoredItem was encoded by a newer coder version %ld. Current "
+ @"coder version is %ld. Some installation data may be lost.",
+ (long)storageVersion, (long)kFIRInstallationsStoredItemStorageVersion);
+ }
+
+ FIRInstallationsStoredItem *item = [[FIRInstallationsStoredItem alloc] init];
+ item.firebaseInstallationID =
+ [aDecoder decodeObjectOfClass:[NSString class]
+ forKey:kFIRInstallationsStoredItemFirebaseInstallationIDKey];
+ item.refreshToken = [aDecoder decodeObjectOfClass:[NSString class]
+ forKey:kFIRInstallationsStoredItemRefreshTokenKey];
+ item.authToken = [aDecoder decodeObjectOfClass:[FIRInstallationsStoredAuthToken class]
+ forKey:kFIRInstallationsStoredItemAuthTokenKey];
+ item.registrationStatus =
+ [aDecoder decodeIntegerForKey:kFIRInstallationsStoredItemRegistrationStatusKey];
+ item.IIDDefaultToken =
+ [aDecoder decodeObjectOfClass:[NSString class]
+ forKey:kFIRInstallationsStoredItemIIDDefaultTokenKey];
+
+ return item;
+}
+
++ (BOOL)supportsSecureCoding {
+ return YES;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallations.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallations.h
new file mode 100644
index 000000000..4839b4e03
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallations.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+@class FIRApp;
+@class FIRInstallationsAuthTokenResult;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/** A notification with this name is sent each time an installation is created or deleted. */
+FOUNDATION_EXPORT const NSNotificationName FIRInstallationIDDidChangeNotification;
+/** `userInfo` key for the `FirebaseApp.name` in `FIRInstallationIDDidChangeNotification`. */
+FOUNDATION_EXPORT NSString *const kFIRInstallationIDDidChangeNotificationAppNameKey;
+
+/**
+ * An installation ID handler block.
+ * @param identifier The installation ID string if exists or `nil` otherwise.
+ * @param error The error when `identifier == nil` or `nil` otherwise.
+ */
+typedef void (^FIRInstallationsIDHandler)(NSString *__nullable identifier,
+ NSError *__nullable error)
+ NS_SWIFT_NAME(InstallationsIDHandler);
+
+/**
+ * An authorization token handler block.
+ * @param tokenResult An instance of `InstallationsAuthTokenResult` in case of success or `nil`
+ * otherwise.
+ * @param error The error when `tokenResult == nil` or `nil` otherwise.
+ */
+typedef void (^FIRInstallationsTokenHandler)(
+ FIRInstallationsAuthTokenResult *__nullable tokenResult, NSError *__nullable error)
+ NS_SWIFT_NAME(InstallationsTokenHandler);
+
+/**
+ * The class provides API for Firebase Installations.
+ * Each configured `FirebaseApp` has a corresponding single instance of `Installations`.
+ * An instance of the class provides access to the installation info for the `FirebaseApp` as well
+ * as the ability to delete it. A Firebase Installation is unique by `FirebaseApp.name` and
+ * `FirebaseApp.options.googleAppID` .
+ */
+NS_SWIFT_NAME(Installations)
+@interface FIRInstallations : NSObject
+
+- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ * Returns a default instance of `Installations`.
+ * @returns An instance of `Installations` for `FirebaseApp.defaultApp().
+ * @throw Throws an exception if the default app is not configured yet or required `FirebaseApp`
+ * options are missing.
+ */
++ (FIRInstallations *)installations NS_SWIFT_NAME(installations());
+
+/**
+ * Returns an instance of `Installations` for an application.
+ * @param application A configured `FirebaseApp` instance.
+ * @returns An instance of `Installations` corresponding to the passed application.
+ * @throw Throws an exception if required `FirebaseApp` options are missing.
+ */
++ (FIRInstallations *)installationsWithApp:(FIRApp *)application NS_SWIFT_NAME(installations(app:));
+
+/**
+ * The method creates or retrieves an installation ID. The installation ID is a stable identifier
+ * that uniquely identifies the app instance. NOTE: If the application already has an existing
+ * FirebaseInstanceID then the InstanceID identifier will be used.
+ * @param completion A completion handler which is invoked when the operation completes. See
+ * `InstallationsIDHandler` for additional details.
+ */
+- (void)installationIDWithCompletion:(FIRInstallationsIDHandler)completion;
+
+/**
+ * Retrieves (locally if it exists or from the server) a valid authorization token. An existing
+ * token may be invalidated or expired, so it is recommended to fetch the auth token before each
+ * server request. The method does the same as `Installations.authTokenForcingRefresh(:,
+ * completion:)` with forcing refresh `NO`.
+ * @param completion A completion handler which is invoked when the operation completes. See
+ * `InstallationsTokenHandler` for additional details.
+ */
+- (void)authTokenWithCompletion:(FIRInstallationsTokenHandler)completion;
+
+/**
+ * Retrieves (locally or from the server depending on `forceRefresh` value) a valid authorization
+ * token. An existing token may be invalidated or expire, so it is recommended to fetch the auth
+ * token before each server request. This method should be used with `forceRefresh == YES` when e.g.
+ * a request with the previously fetched auth token failed with "Not Authorized" error.
+ * @param forceRefresh If `YES` then the locally cached auth token will be ignored and a new one
+ * will be requested from the server. If `NO`, then the locally cached auth token will be returned
+ * if exists and has not expired yet.
+ * @param completion A completion handler which is invoked when the operation completes. See
+ * `InstallationsTokenHandler` for additional details.
+ */
+- (void)authTokenForcingRefresh:(BOOL)forceRefresh
+ completion:(FIRInstallationsTokenHandler)completion;
+
+/**
+ * Deletes all the installation data including the unique identifier, auth tokens and
+ * all related data on the server side. A network connection is required for the method to
+ * succeed. If fails, the existing installation data remains untouched.
+ * @param completion A completion handler which is invoked when the operation completes. `error ==
+ * nil` indicates success.
+ */
+- (void)deleteWithCompletion:(void (^)(NSError *__nullable error))completion;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsAuthTokenResult.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsAuthTokenResult.h
new file mode 100644
index 000000000..7753132d9
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsAuthTokenResult.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+/** The class represents a result of the auth token request. */
+NS_SWIFT_NAME(InstallationsAuthTokenResult)
+@interface FIRInstallationsAuthTokenResult : NSObject
+
+/** The authorization token string. */
+@property(nonatomic, readonly) NSString *authToken;
+
+/** The auth token expiration date. */
+@property(nonatomic, readonly) NSDate *expirationDate;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsErrors.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsErrors.h
new file mode 100644
index 000000000..d0c3b9961
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsErrors.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+extern NSString *const kFirebaseInstallationsErrorDomain;
+
+typedef NS_ENUM(NSUInteger, FIRInstallationsErrorCode) {
+ /** Unknown error. See `userInfo` for details. */
+ FIRInstallationsErrorCodeUnknown = 0,
+
+ /** Keychain error. See `userInfo` for details. */
+ FIRInstallationsErrorCodeKeychain = 1,
+
+ /** Server unreachable. A network error or server is unavailable. See `userInfo` for details. */
+ FIRInstallationsErrorCodeServerUnreachable = 2,
+
+ /** FirebaseApp configuration issues e.g. invalid GMP-App-ID, etc. See `userInfo` for details. */
+ FIRInstallationsErrorCodeInvalidConfiguration = 3,
+
+} NS_SWIFT_NAME(InstallationsErrorCode);
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsVersion.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsVersion.h
new file mode 100644
index 000000000..8cdf6778b
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FIRInstallationsVersion.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+FOUNDATION_EXPORT const char *const FIRInstallationsVersionStr;
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations.h
new file mode 100644
index 000000000..accc9ac6b
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallations.h"
+#import "FIRInstallationsAuthTokenResult.h"
+#import "FIRInstallationsErrors.h"
+#import "FIRInstallationsVersion.h"
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRInstallationsKeychainUtils.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRInstallationsKeychainUtils.h
new file mode 100644
index 000000000..4d73ec00f
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRInstallationsKeychainUtils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// Helper functions to access Keychain.
+@interface FIRInstallationsKeychainUtils : NSObject
+
++ (nullable NSData *)getItemWithQuery:(NSDictionary *)query
+ error:(NSError *_Nullable *_Nullable)outError;
+
++ (BOOL)setItem:(NSData *)item
+ withQuery:(NSDictionary *)query
+ error:(NSError *_Nullable *_Nullable)outError;
+
++ (BOOL)removeItemWithQuery:(NSDictionary *)query error:(NSError *_Nullable *_Nullable)outError;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRInstallationsKeychainUtils.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRInstallationsKeychainUtils.m
new file mode 100644
index 000000000..51da86a8a
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRInstallationsKeychainUtils.m
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRInstallationsKeychainUtils.h"
+
+#import "FIRInstallationsErrorUtil.h"
+
+@implementation FIRInstallationsKeychainUtils
+
++ (nullable NSData *)getItemWithQuery:(NSDictionary *)query
+ error:(NSError *_Nullable *_Nullable)outError {
+ NSMutableDictionary *mutableQuery = [query mutableCopy];
+
+ mutableQuery[(__bridge id)kSecReturnData] = @YES;
+ mutableQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;
+
+ CFDataRef result = NULL;
+ OSStatus status =
+ SecItemCopyMatching((__bridge CFDictionaryRef)mutableQuery, (CFTypeRef *)&result);
+
+ if (status == errSecSuccess && result != NULL) {
+ if (outError) {
+ *outError = nil;
+ }
+
+ return (__bridge_transfer NSData *)result;
+ }
+
+ if (status == errSecItemNotFound) {
+ if (outError) {
+ *outError = nil;
+ }
+ } else {
+ if (outError) {
+ *outError = [FIRInstallationsErrorUtil keychainErrorWithFunction:@"SecItemCopyMatching"
+ status:status];
+ }
+ }
+ return nil;
+}
+
++ (BOOL)setItem:(NSData *)item
+ withQuery:(NSDictionary *)query
+ error:(NSError *_Nullable *_Nullable)outError {
+ NSData *existingItem = [self getItemWithQuery:query error:outError];
+ if (outError && *outError) {
+ return NO;
+ }
+
+ NSMutableDictionary *mutableQuery = [query mutableCopy];
+ mutableQuery[(__bridge id)kSecAttrAccessible] =
+ (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
+
+ OSStatus status;
+ if (!existingItem) {
+ mutableQuery[(__bridge id)kSecValueData] = item;
+ status = SecItemAdd((__bridge CFDictionaryRef)mutableQuery, NULL);
+ } else {
+ NSDictionary *attributes = @{(__bridge id)kSecValueData : item};
+ status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes);
+ }
+
+ if (status == noErr) {
+ if (outError) {
+ *outError = nil;
+ }
+ return YES;
+ }
+
+ NSString *function = existingItem ? @"SecItemUpdate" : @"SecItemAdd";
+ if (outError) {
+ *outError = [FIRInstallationsErrorUtil keychainErrorWithFunction:function status:status];
+ }
+ return NO;
+}
+
++ (BOOL)removeItemWithQuery:(NSDictionary *)query error:(NSError *_Nullable *_Nullable)outError {
+ OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query);
+
+ if (status == noErr || status == errSecItemNotFound) {
+ if (outError) {
+ *outError = nil;
+ }
+ return YES;
+ }
+
+ if (outError) {
+ *outError = [FIRInstallationsErrorUtil keychainErrorWithFunction:@"SecItemDelete"
+ status:status];
+ }
+ return NO;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRSecureStorage.h b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRSecureStorage.h
new file mode 100644
index 000000000..5548e3e12
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRSecureStorage.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+
+@class FBLPromise;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// The class provides a convenient abstraction on top of the iOS Keychain API to save data.
+@interface FIRSecureStorage : NSObject
+
+/**
+ * Get an object by key.
+ * @param key The key.
+ * @param objectClass The expected object class required by `NSSecureCoding`.
+ * @param accessGroup The Keychain Access Group.
+ *
+ * @return Returns a promise. It is resolved with an object stored by key if exists. It is resolved
+ * with `nil` when the object not found. It fails on a Keychain error.
+ */
+- (FBLPromise> *)getObjectForKey:(NSString *)key
+ objectClass:(Class)objectClass
+ accessGroup:(nullable NSString *)accessGroup;
+
+/**
+ * Saves the given object by the given key.
+ * @param object The object to store.
+ * @param key The key to store the object. If there is an existing object by the key, it will be
+ * overridden.
+ * @param accessGroup The Keychain Access Group.
+ *
+ * @return Returns which is resolved with `[NSNull null]` on success.
+ */
+- (FBLPromise *)setObject:(id)object
+ forKey:(NSString *)key
+ accessGroup:(nullable NSString *)accessGroup;
+
+/**
+ * Removes the object by the given key.
+ * @param key The key to store the object. If there is an existing object by the key, it will be
+ * overridden.
+ * @param accessGroup The Keychain Access Group.
+ *
+ * @return Returns which is resolved with `[NSNull null]` on success.
+ */
+- (FBLPromise *)removeObjectForKey:(NSString *)key
+ accessGroup:(nullable NSString *)accessGroup;
+
+#if TARGET_OS_OSX
+/// If not `nil`, then only this keychain will be used to save and read data (see
+/// `kSecMatchSearchList` and `kSecUseKeychain`. It is mostly intended to be used by unit tests.
+@property(nonatomic, nullable) SecKeychainRef keychainRef;
+#endif // TARGET_OSX
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRSecureStorage.m b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRSecureStorage.m
new file mode 100644
index 000000000..543e84815
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/SecureStorage/FIRSecureStorage.m
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2019 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FIRSecureStorage.h"
+#import
+
+#if __has_include()
+#import
+#else
+#import "FBLPromises.h"
+#endif
+
+#import "FIRInstallationsErrorUtil.h"
+#import "FIRInstallationsKeychainUtils.h"
+
+@interface FIRSecureStorage ()
+@property(nonatomic, readonly) dispatch_queue_t keychainQueue;
+@property(nonatomic, readonly) dispatch_queue_t inMemoryCacheQueue;
+@property(nonatomic, readonly) NSString *service;
+@property(nonatomic, readonly) NSCache> *inMemoryCache;
+@end
+
+@implementation FIRSecureStorage
+
+- (instancetype)init {
+ NSCache *cache = [[NSCache alloc] init];
+ // Cache up to 5 installations.
+ cache.countLimit = 5;
+ return [self initWithService:@"com.firebase.FIRInstallations.installations" cache:cache];
+}
+
+- (instancetype)initWithService:(NSString *)service cache:(NSCache *)cache {
+ self = [super init];
+ if (self) {
+ _keychainQueue = dispatch_queue_create(
+ "com.firebase.FIRInstallations.FIRSecureStorage.Keychain", DISPATCH_QUEUE_SERIAL);
+ _inMemoryCacheQueue = dispatch_queue_create(
+ "com.firebase.FIRInstallations.FIRSecureStorage.InMemoryCache", DISPATCH_QUEUE_SERIAL);
+ _service = [service copy];
+ _inMemoryCache = cache;
+ }
+ return self;
+}
+
+#pragma mark - Public
+
+- (FBLPromise> *)getObjectForKey:(NSString *)key
+ objectClass:(Class)objectClass
+ accessGroup:(nullable NSString *)accessGroup {
+ return [FBLPromise onQueue:self.inMemoryCacheQueue
+ do:^id _Nullable {
+ // Return cached object or fail otherwise.
+ id object = [self.inMemoryCache objectForKey:key];
+ return object
+ ?: [[NSError alloc]
+ initWithDomain:FBLPromiseErrorDomain
+ code:FBLPromiseErrorCodeValidationFailure
+ userInfo:nil];
+ }]
+ .recover(^id _Nullable(NSError *error) {
+ // Look for the object in the keychain.
+ return [self getObjectFromKeychainForKey:key
+ objectClass:objectClass
+ accessGroup:accessGroup];
+ });
+}
+
+- (FBLPromise *)setObject:(id)object
+ forKey:(NSString *)key
+ accessGroup:(nullable NSString *)accessGroup {
+ return [FBLPromise onQueue:self.inMemoryCacheQueue
+ do:^id _Nullable {
+ // Save to the in-memory cache first.
+ [self.inMemoryCache setObject:object forKey:[key copy]];
+ return [NSNull null];
+ }]
+ .thenOn(self.keychainQueue, ^id(id result) {
+ // Then store the object to the keychain.
+ NSDictionary *query = [self keychainQueryWithKey:key accessGroup:accessGroup];
+ NSError *error;
+ NSData *encodedObject = [self archiveDataForObject:object error:&error];
+ if (!encodedObject) {
+ return error;
+ }
+
+ if (![FIRInstallationsKeychainUtils setItem:encodedObject withQuery:query error:&error]) {
+ return error;
+ }
+
+ return [NSNull null];
+ });
+}
+
+- (FBLPromise *)removeObjectForKey:(NSString *)key
+ accessGroup:(nullable NSString *)accessGroup {
+ return [FBLPromise onQueue:self.inMemoryCacheQueue
+ do:^id _Nullable {
+ [self.inMemoryCache removeObjectForKey:key];
+ return nil;
+ }]
+ .thenOn(self.keychainQueue, ^id(id result) {
+ NSDictionary *query = [self keychainQueryWithKey:key accessGroup:accessGroup];
+
+ NSError *error;
+ if (![FIRInstallationsKeychainUtils removeItemWithQuery:query error:&error]) {
+ return error;
+ }
+
+ return [NSNull null];
+ });
+}
+
+#pragma mark - Private
+
+- (FBLPromise> *)getObjectFromKeychainForKey:(NSString *)key
+ objectClass:(Class)objectClass
+ accessGroup:(nullable NSString *)accessGroup {
+ // Look for the object in the keychain.
+ return [FBLPromise onQueue:self.keychainQueue
+ do:^id {
+ NSDictionary *query = [self keychainQueryWithKey:key
+ accessGroup:accessGroup];
+ NSError *error;
+ NSData *encodedObject =
+ [FIRInstallationsKeychainUtils getItemWithQuery:query error:&error];
+
+ if (error) {
+ return error;
+ }
+ if (!encodedObject) {
+ return nil;
+ }
+ id object = [self unarchivedObjectOfClass:objectClass
+ fromData:encodedObject
+ error:&error];
+ if (error) {
+ return error;
+ }
+
+ return object;
+ }]
+ .thenOn(self.inMemoryCacheQueue,
+ ^id _Nullable(id _Nullable object) {
+ // Save object to the in-memory cache if exists and return the object.
+ if (object) {
+ [self.inMemoryCache setObject:object forKey:[key copy]];
+ }
+ return object;
+ });
+}
+
+- (void)resetInMemoryCache {
+ [self.inMemoryCache removeAllObjects];
+}
+
+#pragma mark - Keychain
+
+- (NSMutableDictionary *)keychainQueryWithKey:(NSString *)key
+ accessGroup:(nullable NSString *)accessGroup {
+ NSMutableDictionary *query = [NSMutableDictionary dictionary];
+
+ query[(__bridge NSString *)kSecClass] = (__bridge NSString *)kSecClassGenericPassword;
+ query[(__bridge NSString *)kSecAttrService] = self.service;
+ query[(__bridge NSString *)kSecAttrAccount] = key;
+
+ if (accessGroup) {
+ query[(__bridge NSString *)kSecAttrAccessGroup] = accessGroup;
+ }
+
+#if TARGET_OS_OSX
+ if (self.keychainRef) {
+ query[(__bridge NSString *)kSecUseKeychain] = (__bridge id)(self.keychainRef);
+ query[(__bridge NSString *)kSecMatchSearchList] = @[ (__bridge id)(self.keychainRef) ];
+ }
+#endif // TARGET_OSX
+
+ return query;
+}
+
+- (nullable NSData *)archiveDataForObject:(id)object error:(NSError **)outError {
+ NSData *archiveData;
+ if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
+ NSError *error;
+ archiveData = [NSKeyedArchiver archivedDataWithRootObject:object
+ requiringSecureCoding:YES
+ error:&error];
+ if (error && outError) {
+ *outError = [FIRInstallationsErrorUtil keyedArchiverErrorWithError:error];
+ }
+ } else {
+ @try {
+ NSMutableData *data = [NSMutableData data];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
+#pragma clang diagnostic pop
+ archiver.requiresSecureCoding = YES;
+
+ [archiver encodeObject:object forKey:NSKeyedArchiveRootObjectKey];
+ [archiver finishEncoding];
+
+ archiveData = [data copy];
+ } @catch (NSException *exception) {
+ if (outError) {
+ *outError = [FIRInstallationsErrorUtil keyedArchiverErrorWithException:exception];
+ }
+ }
+ }
+
+ return archiveData;
+}
+
+- (nullable id)unarchivedObjectOfClass:(Class)class
+ fromData:(NSData *)data
+ error:(NSError **)outError {
+ id object;
+ if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
+ NSError *error;
+ object = [NSKeyedUnarchiver unarchivedObjectOfClass:class fromData:data error:&error];
+ if (error && outError) {
+ *outError = [FIRInstallationsErrorUtil keyedArchiverErrorWithError:error];
+ }
+ } else {
+ @try {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
+#pragma clang diagnostic pop
+ unarchiver.requiresSecureCoding = YES;
+
+ object = [unarchiver decodeObjectOfClass:class forKey:NSKeyedArchiveRootObjectKey];
+ } @catch (NSException *exception) {
+ if (outError) {
+ *outError = [FIRInstallationsErrorUtil keyedArchiverErrorWithException:exception];
+ }
+ }
+ }
+
+ return object;
+}
+
+@end
diff --git a/ios/Pods/FirebaseInstallations/LICENSE b/ios/Pods/FirebaseInstallations/LICENSE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/ios/Pods/FirebaseInstallations/README.md b/ios/Pods/FirebaseInstallations/README.md
new file mode 100644
index 000000000..3ddc8fbd2
--- /dev/null
+++ b/ios/Pods/FirebaseInstallations/README.md
@@ -0,0 +1,251 @@
+# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk)
+
+This repository contains a subset of the Firebase iOS SDK source. It currently
+includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
+FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
+FirebaseInAppMessagingDisplay, FirebaseMessaging, FirebaseRemoteConfig, and
+FirebaseStorage.
+
+The repository also includes GoogleUtilities source. The
+[GoogleUtilities](GoogleUtilities/README.md) pod is
+a set of utilities used by Firebase and other Google products.
+
+Firebase is an app development platform with tools to help you build, grow and
+monetize your app. More information about Firebase can be found at
+[https://firebase.google.com](https://firebase.google.com).
+
+## Installation
+
+See the three subsections for details about three different installation methods.
+1. [Standard pod install](README.md#standard-pod-install)
+1. [Installing from the GitHub repo](README.md#installing-from-github)
+1. [Experimental Carthage](README.md#carthage-ios-only)
+
+### Standard pod install
+
+Go to
+[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup).
+
+### Installing from GitHub
+
+For releases starting with 5.0.0, the source for each release is also deployed
+to CocoaPods master and available via standard
+[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod).
+
+These instructions can be used to access the Firebase repo at other branches,
+tags, or commits.
+
+#### Background
+
+See
+[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod)
+for instructions and options about overriding pod source locations.
+
+#### Accessing Firebase Source Snapshots
+
+All of the official releases are tagged in this repo and available via CocoaPods. To access a local
+source snapshot or unreleased branch, use Podfile directives like the following:
+
+To access FirebaseFirestore via a branch:
+```
+pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'
+pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master'
+```
+
+To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do:
+
+```
+pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk'
+pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk'
+```
+
+### Carthage (iOS only)
+
+Instructions for the experimental Carthage distribution are at
+[Carthage](Carthage.md).
+
+### Rome
+
+Instructions for installing binary frameworks via
+[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md).
+
+## Development
+
+To develop Firebase software in this repository, ensure that you have at least
+the following software:
+
+ * Xcode 10.1 (or later)
+ * CocoaPods 1.7.2 (or later)
+ * [CocoaPods generate](https://github.com/square/cocoapods-generate)
+
+For the pod that you want to develop:
+
+`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios`
+
+Note: If the CocoaPods cache is out of date, you may need to run
+`pod repo update` before the `pod gen` command.
+
+Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for
+those platforms. Since 10.2, Xcode does not properly handle multi-platform
+CocoaPods workspaces.
+
+Firestore has a self contained Xcode project. See
+[Firestore/README.md](Firestore/README.md).
+
+### Development for Catalyst
+* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios`
+* Check the Mac box in the App-iOS Build Settings
+* Sign the App in the Settings Signing & Capabilities tab
+* Click Pods in the Project Manager
+* Add Signing to the iOS host app and unit test targets
+* Select the Unit-unit scheme
+* Run it to build and test
+
+### Adding a New Firebase Pod
+
+See [AddNewPod.md](AddNewPod.md).
+
+### Code Formatting
+
+To ensure that the code is formatted consistently, run the script
+[./scripts/style.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/style.sh)
+before creating a PR.
+
+Travis will verify that any code changes are done in a style compliant way. Install
+`clang-format` and `swiftformat`.
+These commands will get the right versions:
+
+```
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/e3496d9/Formula/clang-format.rb
+brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/7963c3d/Formula/swiftformat.rb
+```
+
+Note: if you already have a newer version of these installed you may need to
+`brew switch` to this version.
+
+To update this section, find the versions of clang-format and swiftformat.rb to
+match the versions in the CI failure logs
+[here](https://github.com/Homebrew/homebrew-core/tree/master/Formula).
+
+### Running Unit Tests
+
+Select a scheme and press Command-u to build a component and run its unit tests.
+
+#### Viewing Code Coverage
+
+First, make sure that [xcov](https://github.com/nakiostudio/xcov) is installed with `gem install xcov`.
+
+After running the `AllUnitTests_iOS` scheme in Xcode, execute
+`xcov --workspace Firebase.xcworkspace --scheme AllUnitTests_iOS --output_directory xcov_output`
+at Example/ in the terminal. This will aggregate the coverage, and you can run `open xcov_output/index.html` to see the results.
+
+### Running Sample Apps
+In order to run the sample apps and integration tests, you'll need valid
+`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist
+files without real values, but can be replaced with real plist files. To get your own
+`GoogleService-Info.plist` files:
+
+1. Go to the [Firebase Console](https://console.firebase.google.com/)
+2. Create a new Firebase project, if you don't already have one
+3. For each sample app you want to test, create a new Firebase app with the sample app's bundle
+identifier (e.g. `com.google.Database-Example`)
+4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file
+(e.g. in [Example/Database/App/](Example/Database/App/));
+
+Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require
+special Apple capabilities, and you will have to change the sample app to use a unique bundle
+identifier that you can control in your own Apple Developer account.
+
+## Specific Component Instructions
+See the sections below for any special instructions for those components.
+
+### Firebase Auth
+
+If you're doing specific Firebase Auth development, see
+[the Auth Sample README](Example/Auth/README.md) for instructions about
+building and running the FirebaseAuth pod along with various samples and tests.
+
+### Firebase Database
+
+To run the Database Integration tests, make your database authentication rules
+[public](https://firebase.google.com/docs/database/security/quickstart).
+
+### Firebase Storage
+
+To run the Storage Integration tests, follow the instructions in
+[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m).
+
+#### Push Notifications
+
+Push notifications can only be delivered to specially provisioned App IDs in the developer portal.
+In order to actually test receiving push notifications, you will need to:
+
+1. Change the bundle identifier of the sample app to something you own in your Apple Developer
+account, and enable that App ID for push notifications.
+2. You'll also need to
+[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs)
+at **Project Settings > Cloud Messaging > [Your Firebase App]**.
+3. Ensure your iOS device is added to your Apple Developer portal as a test device.
+
+#### iOS Simulator
+
+The iOS Simulator cannot register for remote notifications, and will not receive push notifications.
+In order to receive push notifications, you'll have to follow the steps above and run the app on a
+physical device.
+
+## Community Supported Efforts
+
+We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are
+very grateful! We'd like to empower as many developers as we can to be able to use Firebase and
+participate in the Firebase community.
+
+### tvOS, macOS, and Catalyst
+Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
+FirebaseDatabase, FirebaseMessaging, FirebaseFirestore,
+FirebaseFunctions, FirebaseRemoteConfig, and FirebaseStorage now compile, run unit tests, and work on
+tvOS, macOS, and Catalyst.
+
+For tvOS, checkout the [Sample](Example/tvOSSample).
+
+Keep in mind that macOS, Catalyst and tvOS are not officially supported by Firebase, and this
+repository is actively developed primarily for iOS. While we can catch basic unit test issues with
+Travis, there may be some changes where the SDK no longer works as expected on macOS or tvOS. If you
+encounter this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues).
+
+To install, add a subset of the following to the Podfile:
+
+```
+pod 'Firebase/ABTesting'
+pod 'Firebase/Auth'
+pod 'Firebase/Database'
+pod 'Firebase/Firestore'
+pod 'Firebase/Functions'
+pod 'Firebase/Messaging'
+pod 'Firebase/RemoteConfig'
+pod 'Firebase/Storage'
+```
+
+#### Additional Catalyst Notes
+
+* FirebaseAuth and FirebaseMessaging require adding `Keychain Sharing Capability`
+to Build Settings.
+* FirebaseFirestore requires signing the
+[gRPC Resource target](https://github.com/firebase/firebase-ios-sdk/issues/3500#issuecomment-518741681).
+
+## Roadmap
+
+See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source
+plans and directions.
+
+## Contributing
+
+See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase
+iOS SDK.
+
+## License
+
+The contents of this repository is licensed under the
+[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0).
+
+Your use of Firebase is governed by the
+[Terms of Service for Firebase Services](https://firebase.google.com/terms/).
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h
index 6d4b6cbb9..e3e36e9df 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRIMessageCode.h
@@ -55,10 +55,10 @@ typedef NS_ENUM(NSInteger, FIRInstanceIDMessageCode) {
kFIRInstanceIDMessageCodeAuthServiceCheckinInProgress = 5004,
// FIRInstanceIDBackupExcludedPlist.m
+ // Do NOT USE 6003
kFIRInstanceIDMessageCodeBackupExcludedPlist000 = 6000,
kFIRInstanceIDMessageCodeBackupExcludedPlist001 = 6001,
kFIRInstanceIDMessageCodeBackupExcludedPlist002 = 6002,
- kFIRInstanceIDMessageCodeBackupExcludedPlistInvalidPlistEnum = 6003,
// FIRInstanceIDCheckinService.m
kFIRInstanceIDMessageCodeService000 = 7000,
kFIRInstanceIDMessageCodeService001 = 7001,
@@ -76,29 +76,12 @@ typedef NS_ENUM(NSInteger, FIRInstanceIDMessageCode) {
kFIRInstanceIDMessageCodeCheckinStore003 = 8003,
kFIRInstanceIDMessageCodeCheckinStoreCheckinPlistDeleted = 8009,
kFIRInstanceIDMessageCodeCheckinStoreCheckinPlistSaved = 8010,
- // FIRInstanceIDKeyPair.m
- // DO NOT USE 9001, 9003
- kFIRInstanceIDMessageCodeKeyPair000 = 9000,
- kFIRInstanceIDMessageCodeKeyPair002 = 9002,
- kFIRInstanceIDMessageCodeKeyPairMigrationError = 9004,
- kFIRInstanceIDMessageCodeKeyPairMigrationSuccess = 9005,
- kFIRInstanceIDMessageCodeKeyPairNoLegacyKeyPair = 9006,
- // FIRInstanceIDKeyPairStore.m
- kFIRInstanceIDMessageCodeKeyPairStore000 = 10000,
- kFIRInstanceIDMessageCodeKeyPairStore001 = 10001,
- kFIRInstanceIDMessageCodeKeyPairStore002 = 10002,
- kFIRInstanceIDMessageCodeKeyPairStore003 = 10003,
- kFIRInstanceIDMessageCodeKeyPairStore004 = 10004,
- kFIRInstanceIDMessageCodeKeyPairStore005 = 10005,
- kFIRInstanceIDMessageCodeKeyPairStore006 = 10006,
- kFIRInstanceIDMessageCodeKeyPairStore007 = 10007,
- kFIRInstanceIDMessageCodeKeyPairStore008 = 10008,
- kFIRInstanceIDMessageCodeKeyPairStoreCouldNotLoadKeyPair = 10009,
- // FIRInstanceIDKeyPairUtilities.m
- kFIRInstanceIDMessageCodeKeyPairUtilities000 = 11000,
- kFIRInstanceIDMessageCodeKeyPairUtilities001 = 11001,
- kFIRInstanceIDMessageCodeKeyPairUtilitiesFirstConcatenateParamNil = 11002,
+ // DO NOT USE 9000 - 9006
+
+ // DO NOT USE 10000 - 10009
+
+ // DO NOT USE 11000 - 11002
// DO NOT USE 12000 - 12014
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m
index a078971dc..c5ffe7a0a 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID+Private.m
@@ -16,14 +16,18 @@
#import "FIRInstanceID+Private.h"
+#import
+
+#import
#import "FIRInstanceIDAuthService.h"
-#import "FIRInstanceIDKeyPairStore.h"
+#import "FIRInstanceIDDefines.h"
#import "FIRInstanceIDTokenManager.h"
+@class FIRInstallations;
+
@interface FIRInstanceID ()
@property(nonatomic, readonly, strong) FIRInstanceIDTokenManager *tokenManager;
-@property(nonatomic, readonly, strong) FIRInstanceIDKeyPairStore *keyPairStore;
@end
@@ -35,8 +39,18 @@
[self.tokenManager.authService fetchCheckinInfoWithHandler:handler];
}
-- (NSString *)appInstanceID:(NSError **)error {
- return [self.keyPairStore appIdentityWithError:error];
+// TODO(#4486): Delete the method, `self.firebaseInstallationsID` and related
+// code for Firebase 7 release.
+- (NSString *)appInstanceID:(NSError **)outError {
+ return self.firebaseInstallationsID;
+}
+
+#pragma mark - Firebase Installations Compatibility
+
+/// Presence of this method indicates that this version of IID uses FirebaseInstallations under the
+/// hood. It is checked by FirebaseInstallations SDK.
++ (BOOL)usesFIS {
+ return YES;
}
@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m
index f52016f97..f9cba4f39 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceID.m
@@ -16,19 +16,21 @@
#import "FIRInstanceID.h"
+#import
+
#import
#import
#import
#import
#import
#import
+#import
#import "FIRInstanceID+Private.h"
#import "FIRInstanceIDAuthService.h"
#import "FIRInstanceIDCheckinPreferences.h"
#import "FIRInstanceIDCombinedHandler.h"
#import "FIRInstanceIDConstants.h"
#import "FIRInstanceIDDefines.h"
-#import "FIRInstanceIDKeyPairStore.h"
#import "FIRInstanceIDLogger.h"
#import "FIRInstanceIDStore.h"
#import "FIRInstanceIDTokenInfo.h"
@@ -58,17 +60,17 @@ int64_t const kMinRetryIntervalForDefaultTokenInSeconds = 10; // 10 second
// change.
NSInteger const kMaxRetryCountForDefaultToken = 5;
-#if TARGET_OS_IOS || TARGET_OS_TV
+#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
static NSString *const kEntitlementsAPSEnvironmentKey = @"Entitlements.aps-environment";
#else
-static NSString *const kEntitlementsAPSEnvironmentKey = @"com.apple.developer.aps-environment";
+static NSString *const kEntitlementsAPSEnvironmentKey =
+ @"Entitlements.com.apple.developer.aps-environment";
#endif
-static NSString *const kEntitlementsKeyForMac = @"Entitlements";
static NSString *const kAPSEnvironmentDevelopmentValue = @"development";
/// FIRMessaging selector that returns the current FIRMessaging auto init
/// enabled flag.
-static NSString *const kFIRInstanceIDFCMSelectorAutoInitEnabled = @"isAutoInitEnabled";
-static NSString *const kFIRInstanceIDFCMSelectorInstance = @"messaging";
+static NSString *const kFIRInstanceIDFCMSelectorAutoInitEnabled =
+ @"isAutoInitEnabledWithUserDefaults:";
static NSString *const kFIRInstanceIDAPNSTokenType = @"APNSTokenType";
static NSString *const kFIRIIDAppReadyToConfigureSDKNotification =
@@ -77,10 +79,6 @@ static NSString *const kFIRIIDAppNameKey = @"FIRAppNameKey";
static NSString *const kFIRIIDErrorDomain = @"com.firebase.instanceid";
static NSString *const kFIRIIDServiceInstanceID = @"InstanceID";
-static NSInteger const kFIRIIDErrorCodeInstanceIDFailed = -121;
-
-typedef void (^FIRInstanceIDKeyPairHandler)(FIRInstanceIDKeyPair *keyPair, NSError *error);
-
/**
* The APNS token type for the app. If the token type is set to `UNKNOWN`
* InstanceID will implicitly try to figure out what the actual token type
@@ -117,13 +115,16 @@ typedef NS_ENUM(NSInteger, FIRInstanceIDAPNSTokenType) {
@property(nonatomic, readwrite, copy) NSString *defaultFCMToken;
@property(nonatomic, readwrite, strong) FIRInstanceIDTokenManager *tokenManager;
-@property(nonatomic, readwrite, strong) FIRInstanceIDKeyPairStore *keyPairStore;
+@property(nonatomic, readwrite, strong) FIRInstallations *installations;
// backoff and retry for default token
@property(nonatomic, readwrite, assign) NSInteger retryCountForDefaultToken;
@property(atomic, strong, nullable)
FIRInstanceIDCombinedHandler *defaultTokenFetchHandler;
+/// A cached value of FID. Should be used only for `-[FIRInstanceID appInstanceID:]`.
+@property(atomic, copy, nullable) NSString *firebaseInstallationsID;
+
@end
// InstanceID doesn't provide any functionality to other components,
@@ -269,6 +270,7 @@ static FIRInstanceID *gInstanceID;
return;
}
+ // Add internal options
NSMutableDictionary *tokenOptions = [NSMutableDictionary dictionary];
if (options.count) {
[tokenOptions addEntriesFromDictionary:options];
@@ -276,13 +278,15 @@ static FIRInstanceID *gInstanceID;
NSString *APNSKey = kFIRInstanceIDTokenOptionsAPNSKey;
NSString *serverTypeKey = kFIRInstanceIDTokenOptionsAPNSIsSandboxKey;
-
if (tokenOptions[APNSKey] != nil && tokenOptions[serverTypeKey] == nil) {
// APNS key was given, but server type is missing. Supply the server type with automatic
// checking. This can happen when the token is requested from FCM, which does not include a
// server type during its request.
tokenOptions[serverTypeKey] = @([self isSandboxApp]);
}
+ if (self.firebaseAppID) {
+ tokenOptions[kFIRInstanceIDTokenOptionsFirebaseAppIDKey] = self.firebaseAppID;
+ }
// comparing enums to ints directly throws a warning
FIRInstanceIDErrorCode noError = INT_MAX;
@@ -296,7 +300,7 @@ static FIRInstanceID *gInstanceID;
errorCode = kFIRInstanceIDErrorCodeInvalidAuthorizedEntity;
} else if (![scope length]) {
errorCode = kFIRInstanceIDErrorCodeInvalidScope;
- } else if (!self.keyPairStore) {
+ } else if (!self.installations) {
errorCode = kFIRInstanceIDErrorCodeInvalidStart;
}
@@ -311,60 +315,50 @@ static FIRInstanceID *gInstanceID;
return;
}
- // TODO(chliangGoogle): Add some validation logic that the APNs token data and sandbox value are
- // supplied in the valid format (NSData and BOOL, respectively).
-
- // Add internal options
- if (self.firebaseAppID) {
- tokenOptions[kFIRInstanceIDTokenOptionsFirebaseAppIDKey] = self.firebaseAppID;
- }
-
FIRInstanceID_WEAKIFY(self);
FIRInstanceIDAuthService *authService = self.tokenManager.authService;
- [authService
- fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences, NSError *error) {
- FIRInstanceID_STRONGIFY(self);
- if (error) {
- newHandler(nil, error);
- return;
- }
+ [authService fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences,
+ NSError *error) {
+ FIRInstanceID_STRONGIFY(self);
+ if (error) {
+ newHandler(nil, error);
+ return;
+ }
- // Only use the token in the cache if the APNSInfo matches what the request's options has.
- // It's possible for the request to be with a newer APNs device token, which should be
- // honored.
+ FIRInstanceID_WEAKIFY(self);
+ [self.installations installationIDWithCompletion:^(NSString *_Nullable identifier,
+ NSError *_Nullable error) {
+ FIRInstanceID_STRONGIFY(self);
+
+ if (error) {
+ NSError *newError =
+ [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair];
+ newHandler(nil, newError);
+
+ } else {
FIRInstanceIDTokenInfo *cachedTokenInfo =
[self.tokenManager cachedTokenInfoWithAuthorizedEntity:authorizedEntity scope:scope];
if (cachedTokenInfo) {
- // Ensure that the cached token matches APNs data before returning it.
FIRInstanceIDAPNSInfo *optionsAPNSInfo =
[[FIRInstanceIDAPNSInfo alloc] initWithTokenOptionsDictionary:tokenOptions];
- // If either the APNs info is missing in both, or if they are an exact match, then we can
- // use this cached token.
+ // Check if APNS Info is changed
if ((!cachedTokenInfo.APNSInfo && !optionsAPNSInfo) ||
[cachedTokenInfo.APNSInfo isEqualToAPNSInfo:optionsAPNSInfo]) {
- newHandler(cachedTokenInfo.token, nil);
- return;
+ // check if token is fresh
+ if ([cachedTokenInfo isFreshWithIID:identifier]) {
+ newHandler(cachedTokenInfo.token, nil);
+ return;
+ }
}
}
-
- FIRInstanceID_WEAKIFY(self);
- [self asyncLoadKeyPairWithHandler:^(FIRInstanceIDKeyPair *keyPair, NSError *error) {
- FIRInstanceID_STRONGIFY(self);
-
- if (error) {
- NSError *newError =
- [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair];
- newHandler(nil, newError);
-
- } else {
- [self.tokenManager fetchNewTokenWithAuthorizedEntity:[authorizedEntity copy]
- scope:[scope copy]
- keyPair:keyPair
- options:tokenOptions
- handler:newHandler];
- }
- }];
- }];
+ [self.tokenManager fetchNewTokenWithAuthorizedEntity:[authorizedEntity copy]
+ scope:[scope copy]
+ instanceID:identifier
+ options:tokenOptions
+ handler:newHandler];
+ }
+ }];
+ }];
}
- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity
@@ -383,7 +377,7 @@ static FIRInstanceID *gInstanceID;
errorCode = kFIRInstanceIDErrorCodeInvalidAuthorizedEntity;
} else if (![scope length]) {
errorCode = kFIRInstanceIDErrorCodeInvalidScope;
- } else if (!self.keyPairStore) {
+ } else if (!self.installations) {
errorCode = kFIRInstanceIDErrorCodeInvalidStart;
}
@@ -414,7 +408,8 @@ static FIRInstanceID *gInstanceID;
}
FIRInstanceID_WEAKIFY(self);
- [self asyncLoadKeyPairWithHandler:^(FIRInstanceIDKeyPair *keyPair, NSError *error) {
+ [self.installations installationIDWithCompletion:^(NSString *_Nullable identifier,
+ NSError *_Nullable error) {
FIRInstanceID_STRONGIFY(self);
if (error) {
NSError *newError =
@@ -424,41 +419,13 @@ static FIRInstanceID *gInstanceID;
} else {
[self.tokenManager deleteTokenWithAuthorizedEntity:authorizedEntity
scope:scope
- keyPair:keyPair
+ instanceID:identifier
handler:newHandler];
}
}];
}];
}
-- (void)asyncLoadKeyPairWithHandler:(FIRInstanceIDKeyPairHandler)handler {
- FIRInstanceID_WEAKIFY(self);
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- FIRInstanceID_STRONGIFY(self);
-
- NSError *error = nil;
- FIRInstanceIDKeyPair *keyPair = [self.keyPairStore loadKeyPairWithError:&error];
- dispatch_async(dispatch_get_main_queue(), ^{
- if (error) {
- FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID002,
- @"Failed to retreieve keyPair %@", error);
- if (handler) {
- handler(nil, error);
- }
- } else if (!keyPair && !error) {
- if (handler) {
- handler(nil,
- [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair]);
- }
- } else {
- if (handler) {
- handler(keyPair, nil);
- }
- }
- });
- });
-}
-
#pragma mark - Identity
- (void)getIDWithHandler:(FIRInstanceIDHandler)handler {
@@ -468,30 +435,17 @@ static FIRInstanceID *gInstanceID;
return;
}
- void (^callHandlerOnMainThread)(NSString *, NSError *) = ^(NSString *identity, NSError *error) {
- dispatch_async(dispatch_get_main_queue(), ^{
- handler(identity, error);
- });
- };
-
- if (!self.keyPairStore) {
- NSError *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidStart];
- callHandlerOnMainThread(nil, error);
- return;
- }
-
FIRInstanceID_WEAKIFY(self);
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- FIRInstanceID_STRONGIFY(self);
- NSError *error;
- NSString *appIdentity = [self.keyPairStore appIdentityWithError:&error];
- // When getID is explicitly called, trigger getToken to make sure token always exists.
- // This is to avoid ID conflict (ID is not checked for conflict until we generate a token)
- if (appIdentity) {
- [self token];
- }
- callHandlerOnMainThread(appIdentity, error);
- });
+ [self.installations
+ installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) {
+ FIRInstanceID_STRONGIFY(self);
+ // When getID is explicitly called, trigger getToken to make sure token always exists.
+ // This is to avoid ID conflict (ID is not checked for conflict until we generate a token)
+ if (identifier) {
+ [self token];
+ }
+ handler(identifier, error);
+ }];
}
- (void)deleteIDWithHandler:(FIRInstanceIDDeleteHandler)handler {
@@ -511,7 +465,7 @@ static FIRInstanceID *gInstanceID;
});
};
- if (!self.keyPairStore) {
+ if (!self.installations) {
FIRInstanceIDErrorCode error = kFIRInstanceIDErrorCodeInvalidStart;
callHandlerOnMainThread([NSError errorWithFIRInstanceIDErrorCode:error]);
return;
@@ -529,16 +483,17 @@ static FIRInstanceID *gInstanceID;
}];
};
- [self asyncLoadKeyPairWithHandler:^(FIRInstanceIDKeyPair *keyPair, NSError *error) {
- FIRInstanceID_STRONGIFY(self);
- if (error) {
- NSError *newError =
- [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair];
- callHandlerOnMainThread(newError);
- } else {
- [self.tokenManager deleteAllTokensWithKeyPair:keyPair handler:deleteTokensHandler];
- }
- }];
+ [self.installations
+ installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) {
+ FIRInstanceID_STRONGIFY(self);
+ if (error) {
+ NSError *newError =
+ [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPair];
+ callHandlerOnMainThread(newError);
+ } else {
+ [self.tokenManager deleteAllTokensWithInstanceID:identifier handler:deleteTokensHandler];
+ }
+ }];
}
- (void)notifyIdentityReset {
@@ -559,52 +514,36 @@ static FIRInstanceID *gInstanceID;
}
// Delete Instance ID.
- [self.keyPairStore
- deleteSavedKeyPairWithSubtype:kFIRInstanceIDKeyPairSubType
- handler:^(NSError *error) {
- NSError *deletePlistError;
- [self.keyPairStore
- removeKeyPairCreationTimePlistWithError:&deletePlistError];
- if (error || deletePlistError) {
- if (handler) {
- // Prefer to use the delete Instance ID error.
- error = [NSError
- errorWithFIRInstanceIDErrorCode:
- kFIRInstanceIDErrorCodeUnknown
- userInfo:@{
- NSUnderlyingErrorKey : error
- ? error
- : deletePlistError
- }];
- handler(error);
- }
- return;
- }
- // Delete checkin.
- [self.tokenManager.authService
- resetCheckinWithHandler:^(NSError *error) {
- if (error) {
- if (handler) {
- handler(error);
- }
- return;
- }
- // Only request new token if FCM auto initialization is
- // enabled.
- if ([self isFCMAutoInitEnabled]) {
- // Deletion succeeds! Requesting new checkin, IID and token.
- // TODO(chliangGoogle) see if dispatch_after is necessary
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
- (int64_t)(0.5 * NSEC_PER_SEC)),
- dispatch_get_main_queue(), ^{
- [self defaultTokenWithHandler:nil];
- });
- }
- if (handler) {
- handler(nil);
- }
- }];
- }];
+ [self.installations deleteWithCompletion:^(NSError *_Nullable error) {
+ if (error) {
+ if (handler) {
+ handler(error);
+ }
+ return;
+ }
+
+ [self.tokenManager.authService resetCheckinWithHandler:^(NSError *error) {
+ if (error) {
+ if (handler) {
+ handler(error);
+ }
+ return;
+ }
+ // Only request new token if FCM auto initialization is
+ // enabled.
+ if ([self isFCMAutoInitEnabled]) {
+ // Deletion succeeds! Requesting new checkin, IID and token.
+ // TODO(chliangGoogle) see if dispatch_after is necessary
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)),
+ dispatch_get_main_queue(), ^{
+ [self defaultTokenWithHandler:nil];
+ });
+ }
+ if (handler) {
+ handler(nil);
+ }
+ }];
+ }];
}];
}
@@ -639,67 +578,53 @@ static FIRInstanceID *gInstanceID;
+ (nonnull NSArray *)componentsToRegister {
FIRComponentCreationBlock creationBlock =
^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
+ // InstanceID only works with the default app.
+ if (!container.app.isDefaultApp) {
+ // Only configure for the default FIRApp.
+ FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeFIRApp002,
+ @"Firebase Instance ID only works with the default app.");
+ return nil;
+ }
+
// Ensure it's cached so it returns the same instance every time instanceID is called.
*isCacheable = YES;
FIRInstanceID *instanceID = [[FIRInstanceID alloc] initPrivately];
[instanceID start];
+ [instanceID configureInstanceIDWithOptions:container.app.options];
return instanceID;
};
FIRComponent *instanceIDProvider =
[FIRComponent componentWithProtocol:@protocol(FIRInstanceIDInstanceProvider)
- instantiationTiming:FIRInstantiationTimingLazy
+ instantiationTiming:FIRInstantiationTimingEagerInDefaultApp
dependencies:@[]
creationBlock:creationBlock];
return @[ instanceIDProvider ];
}
-+ (void)configureWithApp:(FIRApp *)app {
- if (!app.isDefaultApp) {
- // Only configure for the default FIRApp.
- FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeFIRApp002,
- @"Firebase Instance ID only works with the default app.");
- return;
- }
- [[FIRInstanceID instanceID] configureInstanceIDWithOptions:app.options app:app];
-}
-
-- (void)configureInstanceIDWithOptions:(FIROptions *)options app:(FIRApp *)firApp {
+- (void)configureInstanceIDWithOptions:(FIROptions *)options {
NSString *GCMSenderID = options.GCMSenderID;
if (!GCMSenderID.length) {
FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeFIRApp000,
@"Firebase not set up correctly, nil or empty senderID.");
- [FIRInstanceID exitWithReason:@"GCM_SENDER_ID must not be nil or empty." forFirebaseApp:firApp];
- return;
+ [NSException raise:kFIRIIDErrorDomain
+ format:@"Could not configure Firebase InstanceID. GCMSenderID must not be nil or "
+ @"empty."];
}
self.fcmSenderID = GCMSenderID;
- self.firebaseAppID = firApp.options.googleAppID;
+ self.firebaseAppID = options.googleAppID;
+
+ [self updateFirebaseInstallationID];
// FCM generates a FCM token during app start for sending push notification to device.
- // This is not needed for app extension.
+ // This is not needed for app extension except for watch.
+#if TARGET_OS_WATCH
+ [self didCompleteConfigure];
+#else
if (![GULAppEnvironmentUtil isAppExtension]) {
[self didCompleteConfigure];
}
-}
-
-+ (NSError *)configureErrorWithReason:(nonnull NSString *)reason {
- NSString *description =
- [NSString stringWithFormat:@"Configuration failed for service %@.", kFIRIIDServiceInstanceID];
- if (!reason.length) {
- reason = @"Unknown reason";
- }
-
- NSDictionary *userInfo =
- @{NSLocalizedDescriptionKey : description, NSLocalizedFailureReasonErrorKey : reason};
-
- return [NSError errorWithDomain:kFIRIIDErrorDomain
- code:kFIRIIDErrorCodeInstanceIDFailed
- userInfo:userInfo];
-}
-
-+ (void)exitWithReason:(nonnull NSString *)reason forFirebaseApp:(FIRApp *)firebaseApp {
- [NSException raise:kFIRIIDErrorDomain
- format:@"Could not configure Firebase InstanceID. %@", reason];
+#endif
}
// This is used to start any operations when we receive FirebaseSDK setup notification
@@ -709,12 +634,15 @@ static FIRInstanceID *gInstanceID;
// When there is a cached token, do the token refresh.
if (cachedToken) {
// Clean up expired tokens by checking the token refresh policy.
- if ([self.tokenManager checkForTokenRefreshPolicy]) {
- // Default token is expired, fetch default token from server.
- [self defaultTokenWithHandler:nil];
- }
- // Notify FCM with the default token.
- self.defaultFCMToken = [self token];
+ [self.installations
+ installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) {
+ if ([self.tokenManager checkTokenRefreshPolicyWithIID:identifier]) {
+ // Default token is expired, fetch default token from server.
+ [self defaultTokenWithHandler:nil];
+ }
+ // Notify FCM with the default token.
+ self.defaultFCMToken = [self token];
+ }];
} else if ([self isFCMAutoInitEnabled]) {
// When there is no cached token, must check auto init is enabled.
// If it's disabled, don't initiate token generation/refresh.
@@ -736,29 +664,20 @@ static FIRInstanceID *gInstanceID;
return NO;
}
- // Messaging doesn't have the singleton method, auto init should be enabled since FCM exists.
- SEL instanceSelector = NSSelectorFromString(kFIRInstanceIDFCMSelectorInstance);
- if (![messagingClass respondsToSelector:instanceSelector]) {
- return YES;
- }
-
- // Get FIRMessaging shared instance.
- IMP messagingInstanceIMP = [messagingClass methodForSelector:instanceSelector];
- id (*getMessagingInstance)(id, SEL) = (void *)messagingInstanceIMP;
- id messagingInstance = getMessagingInstance(messagingClass, instanceSelector);
-
- // Messaging doesn't have the property, auto init should be enabled since FCM exists.
+ // Messaging doesn't have the class method, auto init should be enabled since FCM exists.
SEL autoInitSelector = NSSelectorFromString(kFIRInstanceIDFCMSelectorAutoInitEnabled);
- if (![messagingInstance respondsToSelector:autoInitSelector]) {
+ if (![messagingClass respondsToSelector:autoInitSelector]) {
return YES;
}
- // Get autoInitEnabled method.
- IMP isAutoInitEnabledIMP = [messagingInstance methodForSelector:autoInitSelector];
- BOOL (*isAutoInitEnabled)(id, SEL) = (BOOL(*)(id, SEL))isAutoInitEnabledIMP;
+ // Get the autoInitEnabled class method.
+ IMP isAutoInitEnabledIMP = [messagingClass methodForSelector:autoInitSelector];
+ BOOL(*isAutoInitEnabled)
+ (Class, SEL, GULUserDefaults *) = (BOOL(*)(id, SEL, GULUserDefaults *))isAutoInitEnabledIMP;
// Check FCM's isAutoInitEnabled property.
- return isAutoInitEnabled(messagingInstance, autoInitSelector);
+ return isAutoInitEnabled(messagingClass, autoInitSelector,
+ [GULUserDefaults standardUserDefaults]);
}
// Actually makes InstanceID instantiate both the IID and Token-related subsystems.
@@ -768,7 +687,7 @@ static FIRInstanceID *gInstanceID;
}
[self setupTokenManager];
- [self setupKeyPairManager];
+ self.installations = [FIRInstallations installations];
[self setupNotificationListeners];
}
@@ -777,20 +696,6 @@ static FIRInstanceID *gInstanceID;
self.tokenManager = [[FIRInstanceIDTokenManager alloc] init];
}
-// Creates a key pair manager, which stores the public/private keys needed to generate an
-// application instance ID.
-- (void)setupKeyPairManager {
- self.keyPairStore = [[FIRInstanceIDKeyPairStore alloc] init];
- if ([self.keyPairStore invalidateKeyPairsIfNeeded]) {
- // Reset tokens right away when keypair is deleted, otherwise async call can make first query
- // of token happens before reset old tokens during app start.
- // TODO(chliangGoogle): Delete all tokens on server too, using
- // deleteAllTokensWithKeyPair:handler:. This requires actually retrieving the invalid keypair
- // from Keychain, which is something that the key pair store does not currently do.
- [self.tokenManager deleteAllTokensLocallyWithHandler:nil];
- }
-}
-
- (void)setupNotificationListeners {
// To prevent double notifications remove observer from all events during setup.
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
@@ -803,6 +708,7 @@ static FIRInstanceID *gInstanceID;
selector:@selector(notifyAPNSTokenIsSet:)
name:kFIRInstanceIDAPNSTokenNotification
object:nil];
+ [self observeFirebaseInstallationIDChanges];
}
#pragma mark - Private Helpers
@@ -1010,44 +916,46 @@ static FIRInstanceID *gInstanceID;
// they are up-to-date.
if (invalidatedTokens.count > 0) {
FIRInstanceID_WEAKIFY(self);
- [self asyncLoadKeyPairWithHandler:^(FIRInstanceIDKeyPair *keyPair, NSError *error) {
- FIRInstanceID_STRONGIFY(self);
- if (self == nil) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID017,
- @"Instance ID shut down during token reset. Aborting");
- return;
- }
- if (self.apnsTokenData == nil) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID018,
- @"apnsTokenData was set to nil during token reset. Aborting");
- return;
- }
- NSMutableDictionary *tokenOptions = [@{
- kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData,
- kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp)
- } mutableCopy];
- if (self.firebaseAppID) {
- tokenOptions[kFIRInstanceIDTokenOptionsFirebaseAppIDKey] = self.firebaseAppID;
- }
+ [self.installations
+ installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) {
+ FIRInstanceID_STRONGIFY(self);
+ if (self == nil) {
+ FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID017,
+ @"Instance ID shut down during token reset. Aborting");
+ return;
+ }
+ if (self.apnsTokenData == nil) {
+ FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID018,
+ @"apnsTokenData was set to nil during token reset. Aborting");
+ return;
+ }
- for (FIRInstanceIDTokenInfo *tokenInfo in invalidatedTokens) {
- if ([tokenInfo.token isEqualToString:self.defaultFCMToken]) {
- // We will perform a special fetch for the default FCM token, so that the delegate methods
- // are called. For all others, we will do an internal re-fetch.
- [self defaultTokenWithHandler:nil];
- } else {
- [self.tokenManager fetchNewTokenWithAuthorizedEntity:tokenInfo.authorizedEntity
- scope:tokenInfo.scope
- keyPair:keyPair
- options:tokenOptions
- handler:^(NSString *_Nullable token,
- NSError *_Nullable error){
+ NSMutableDictionary *tokenOptions = [@{
+ kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData,
+ kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp)
+ } mutableCopy];
+ if (self.firebaseAppID) {
+ tokenOptions[kFIRInstanceIDTokenOptionsFirebaseAppIDKey] = self.firebaseAppID;
+ }
- }];
- }
- }
- }];
+ for (FIRInstanceIDTokenInfo *tokenInfo in invalidatedTokens) {
+ if ([tokenInfo.token isEqualToString:self.defaultFCMToken]) {
+ // We will perform a special fetch for the default FCM token, so that the delegate
+ // methods are called. For all others, we will do an internal re-fetch.
+ [self defaultTokenWithHandler:nil];
+ } else {
+ [self.tokenManager fetchNewTokenWithAuthorizedEntity:tokenInfo.authorizedEntity
+ scope:tokenInfo.scope
+ instanceID:identifier
+ options:tokenOptions
+ handler:^(NSString *_Nullable token,
+ NSError *_Nullable error){
+
+ }];
+ }
+ }
+ }];
}
}
@@ -1074,7 +982,7 @@ static FIRInstanceID *gInstanceID;
// Apps distributed via AppStore or TestFlight use the Production APNS certificates.
return defaultAppTypeProd;
}
-#if TARGET_OS_IOS || TARGET_OS_TV
+#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
NSString *path = [[[NSBundle mainBundle] bundlePath]
stringByAppendingPathComponent:@"embedded.mobileprovision"];
#elif TARGET_OS_OSX
@@ -1157,13 +1065,7 @@ static FIRInstanceID *gInstanceID;
@"most likely a Dev profile.");
}
-#if TARGET_OS_IOS || TARGET_OS_TV
NSString *apsEnvironment = [plistMap valueForKeyPath:kEntitlementsAPSEnvironmentKey];
-#elif TARGET_OS_OSX
- NSDictionary *entitlements = [plistMap valueForKey:kEntitlementsKeyForMac];
- NSString *apsEnvironment = [entitlements valueForKey:kEntitlementsAPSEnvironmentKey];
-#endif
-
NSString *debugString __unused =
[NSString stringWithFormat:@"APNS Environment in profile: %@", apsEnvironment];
FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID013, @"%@", debugString);
@@ -1194,4 +1096,35 @@ static FIRInstanceID *gInstanceID;
}
}
+#pragma mark - Sync InstanceID
+
+- (void)updateFirebaseInstallationID {
+ FIRInstanceID_WEAKIFY(self);
+ [self.installations
+ installationIDWithCompletion:^(NSString *_Nullable installationID, NSError *_Nullable error) {
+ FIRInstanceID_STRONGIFY(self);
+ self.firebaseInstallationsID = installationID;
+ }];
+}
+
+- (void)installationIDDidChangeNotificationReceived:(NSNotification *)notification {
+ NSString *installationAppID =
+ notification.userInfo[kFIRInstallationIDDidChangeNotificationAppNameKey];
+ if ([installationAppID isKindOfClass:[NSString class]] &&
+ [installationAppID isEqual:self.firebaseAppID]) {
+ [self updateFirebaseInstallationID];
+ }
+}
+
+- (void)observeFirebaseInstallationIDChanges {
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:FIRInstallationIDDidChangeNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(installationIDDidChangeNotificationReceived:)
+ name:FIRInstallationIDDidChangeNotification
+ object:nil];
+}
+
@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h
index 347dddac1..8d453b8b4 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h
@@ -73,25 +73,22 @@ NS_ASSUME_NONNULL_BEGIN
handler:(nullable void (^)(NSError *error))handler;
/**
- * Set the data for a given service and account with a specific accessibility. If
- * accessibility is NULL we use `kSecAttrAccessibleAlwaysThisDeviceOnly` which
+ * Set the data for a given service and account.
+ * We use `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly` which
* prevents backup and restore to iCloud, and works for app extension that can
* execute right after a device is restarted (and not unlocked).
*
* @param data The data to save.
* @param service The `kSecAttrService` used to save the password.
- * @param accessibility The `kSecAttrAccessibility` used to save the password. If NULL
- * set this to `kSecAttrAccessibleAlwaysThisDeviceOnly`.
* @param account The `kSecAttrAccount` used to save the password.
* @param handler The callback handler which is invoked when the add operation is complete,
* with an error if there is any.
*
*/
- (void)setData:(NSData *)data
- forService:(NSString *)service
- accessibility:(nullable CFTypeRef)accessibility
- account:(NSString *)account
- handler:(nullable void (^)(NSError *))handler;
+ forService:(NSString *)service
+ account:(NSString *)account
+ handler:(nullable void (^)(NSError *))handler;
@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m
index 348a915e8..dfce2f75b 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m
@@ -91,7 +91,7 @@ NSString *const kFIRInstanceIDKeychainWildcardIdentifier = @"*";
// FIRInstanceIDKeychain should only take a query and return a result, will handle the query here.
NSArray *passwordInfos =
CFBridgingRelease([[FIRInstanceIDKeychain sharedInstance] itemWithQuery:keychainQuery]);
-#elif TARGET_OS_OSX
+#elif TARGET_OS_OSX || TARGET_OS_WATCH
keychainQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;
NSData *passwordInfos =
CFBridgingRelease([[FIRInstanceIDKeychain sharedInstance] itemWithQuery:keychainQuery]);
@@ -120,7 +120,7 @@ NSString *const kFIRInstanceIDKeychainWildcardIdentifier = @"*";
[results addObject:passwordInfo[(__bridge id)kSecValueData]];
}
}
-#elif TARGET_OS_OSX
+#elif TARGET_OS_OSX || TARGET_OS_WATCH
[results addObject:passwordInfos];
#endif
// We query the keychain because it didn't exist in cache, now query is done, update the result in
@@ -167,10 +167,9 @@ NSString *const kFIRInstanceIDKeychainWildcardIdentifier = @"*";
}
- (void)setData:(NSData *)data
- forService:(NSString *)service
- accessibility:(CFTypeRef)accessibility
- account:(NSString *)account
- handler:(void (^)(NSError *))handler {
+ forService:(NSString *)service
+ account:(NSString *)account
+ handler:(void (^)(NSError *))handler {
if ([service isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier] ||
[account isEqualToString:kFIRInstanceIDKeychainWildcardIdentifier]) {
if (handler) {
@@ -194,14 +193,8 @@ NSString *const kFIRInstanceIDKeychainWildcardIdentifier = @"*";
[self keychainQueryForService:service account:account];
keychainQuery[(__bridge id)kSecValueData] = data;
- if (accessibility != NULL) {
- keychainQuery[(__bridge id)kSecAttrAccessible] =
- (__bridge id)accessibility;
- } else {
- // Defaults to No backup
- keychainQuery[(__bridge id)kSecAttrAccessible] =
- (__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly;
- }
+ keychainQuery[(__bridge id)kSecAttrAccessible] =
+ (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
[[FIRInstanceIDKeychain sharedInstance]
addItemWithQuery:keychainQuery
handler:handler];
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m
index ca930e689..c1085caef 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDBackupExcludedPlist.m
@@ -18,18 +18,10 @@
#import "FIRInstanceIDLogger.h"
-typedef enum : NSUInteger {
- FIRInstanceIDPlistDirectoryUnknown,
- FIRInstanceIDPlistDirectoryDocuments,
- FIRInstanceIDPlistDirectoryApplicationSupport,
-} FIRInstanceIDPlistDirectory;
-
@interface FIRInstanceIDBackupExcludedPlist ()
@property(nonatomic, readwrite, copy) NSString *fileName;
@property(nonatomic, readwrite, copy) NSString *subDirectoryName;
-@property(nonatomic, readwrite, assign) BOOL fileInStandardDirectory;
-
@property(nonatomic, readwrite, strong) NSDictionary *cachedPlistContents;
@end
@@ -41,19 +33,12 @@ typedef enum : NSUInteger {
if (self) {
_fileName = [fileName copy];
_subDirectoryName = [subDirectory copy];
-#if TARGET_OS_IOS
- _fileInStandardDirectory = [self moveToApplicationSupportSubDirectory:subDirectory];
-#else
- // For tvOS and macOS, we never store the content in document folder, so
- // the migration is unnecessary.
- _fileInStandardDirectory = YES;
-#endif
}
return self;
}
- (BOOL)writeDictionary:(NSDictionary *)dict error:(NSError **)error {
- NSString *path = [self plistPathInDirectory:[self plistDirectory]];
+ NSString *path = [self plistPathInDirectory];
if (![dict writeToFile:path atomically:YES]) {
FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlist000,
@"Failed to write to %@.plist", self.fileName);
@@ -85,7 +70,7 @@ typedef enum : NSUInteger {
- (BOOL)deleteFile:(NSError **)error {
BOOL success = YES;
- NSString *path = [self plistPathInDirectory:[self plistDirectory]];
+ NSString *path = [self plistPathInDirectory];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
success = [[NSFileManager defaultManager] removeItemAtPath:path error:error];
}
@@ -96,7 +81,7 @@ typedef enum : NSUInteger {
- (NSDictionary *)contentAsDictionary {
if (!self.cachedPlistContents) {
- NSString *path = [self plistPathInDirectory:[self plistDirectory]];
+ NSString *path = [self plistPathInDirectory];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
self.cachedPlistContents = [[NSDictionary alloc] initWithContentsOfFile:path];
}
@@ -104,93 +89,23 @@ typedef enum : NSUInteger {
return self.cachedPlistContents;
}
-- (BOOL)moveToApplicationSupportSubDirectory:(NSString *)subDirectoryName {
- NSArray *directoryPaths =
- NSSearchPathForDirectoriesInDomains([self supportedDirectory], NSUserDomainMask, YES);
- // This only going to happen inside iOS so it is an applicationSupportDirectory.
- NSString *applicationSupportDirPath = directoryPaths.lastObject;
- NSArray *components = @[ applicationSupportDirPath, subDirectoryName ];
- NSString *subDirectoryPath = [NSString pathWithComponents:components];
- BOOL hasSubDirectory;
- if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath
- isDirectory:&hasSubDirectory]) {
- // Cannot move to non-existent directory
- return NO;
- }
-
- if ([self doesFileExistInDirectory:FIRInstanceIDPlistDirectoryDocuments]) {
- NSString *oldPlistPath = [self plistPathInDirectory:FIRInstanceIDPlistDirectoryDocuments];
- NSString *newPlistPath =
- [self plistPathInDirectory:FIRInstanceIDPlistDirectoryApplicationSupport];
- if ([self doesFileExistInDirectory:FIRInstanceIDPlistDirectoryApplicationSupport]) {
- // File exists in both Documents and ApplicationSupport
- return NO;
- }
- NSError *moveError;
- if (![[NSFileManager defaultManager] moveItemAtPath:oldPlistPath
- toPath:newPlistPath
- error:&moveError]) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlist002,
- @"Failed to move file %@ from %@ to %@. Error: %@", self.fileName,
- oldPlistPath, newPlistPath, moveError);
- return NO;
- }
- }
- // We moved the file if it existed, otherwise we didn't need to do anything
- return YES;
-}
-
- (BOOL)doesFileExist {
- return [self doesFileExistInDirectory:[self plistDirectory]];
+ NSString *path = [self plistPathInDirectory];
+ return [[NSFileManager defaultManager] fileExistsAtPath:path];
}
#pragma mark - Private
-- (FIRInstanceIDPlistDirectory)plistDirectory {
- if (_fileInStandardDirectory) {
- return FIRInstanceIDPlistDirectoryApplicationSupport;
- } else {
- return FIRInstanceIDPlistDirectoryDocuments;
- };
-}
-
-- (NSString *)plistPathInDirectory:(FIRInstanceIDPlistDirectory)directory {
- return [self pathWithName:self.fileName inDirectory:directory];
-}
-
-- (NSString *)pathWithName:(NSString *)plistName
- inDirectory:(FIRInstanceIDPlistDirectory)directory {
+- (NSString *)plistPathInDirectory {
NSArray *directoryPaths;
- NSArray *components = @[];
- NSString *plistNameWithExtension = [NSString stringWithFormat:@"%@.plist", plistName];
- switch (directory) {
- case FIRInstanceIDPlistDirectoryDocuments:
- directoryPaths =
- NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- components = @[ directoryPaths.lastObject, plistNameWithExtension ];
- break;
-
- case FIRInstanceIDPlistDirectoryApplicationSupport:
- directoryPaths =
- NSSearchPathForDirectoriesInDomains([self supportedDirectory], NSUserDomainMask, YES);
- components = @[ directoryPaths.lastObject, _subDirectoryName, plistNameWithExtension ];
- break;
-
- default:
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeBackupExcludedPlistInvalidPlistEnum,
- @"Invalid plist directory type: %lu", (unsigned long)directory);
- NSAssert(NO, @"Invalid plist directory type: %lu", (unsigned long)directory);
- break;
- }
+ NSString *plistNameWithExtension = [NSString stringWithFormat:@"%@.plist", self.fileName];
+ directoryPaths =
+ NSSearchPathForDirectoriesInDomains([self supportedDirectory], NSUserDomainMask, YES);
+ NSArray *components = @[ directoryPaths.lastObject, _subDirectoryName, plistNameWithExtension ];
return [NSString pathWithComponents:components];
}
-- (BOOL)doesFileExistInDirectory:(FIRInstanceIDPlistDirectory)directory {
- NSString *path = [self plistPathInDirectory:directory];
- return [[NSFileManager defaultManager] fileExistsAtPath:path];
-}
-
- (NSSearchPathDirectory)supportedDirectory {
#if TARGET_OS_TV
return NSCachesDirectory;
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m
index 6d2b5ff9a..8b3357967 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinService.m
@@ -210,6 +210,9 @@ static FIRInstanceIDURLRequestTestBlock testBlock;
NSInteger userNumber = 0; // Multi Profile may change this.
NSInteger userSerialNumber = 0; // Multi Profile may change this
+ // This ID is generated for logging purpose and it is only logged for performance
+ // information for backend, not secure information.
+ // TODO(chliang): Talk to backend team to see if this ID is still needed.
uint32_t loggingID = arc4random();
NSString *timeZone = [NSTimeZone localTimeZone].name;
int64_t lastCheckingTimestampMillis = checkinPreferences.lastCheckinTimestampMillis;
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m
index 99715a5b8..114277862 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDCheckinStore.m
@@ -130,7 +130,6 @@ static const NSInteger kOldCheckinPlistCount = 6;
NSData *data = [checkinKeychainContent dataUsingEncoding:NSUTF8StringEncoding];
[self.keychain setData:data
forService:kFIRInstanceIDCheckinKeychainService
- accessibility:nil
account:self.bundleIdentifierForKeychainAccount
handler:^(NSError *error) {
if (error) {
@@ -225,7 +224,6 @@ static const NSInteger kOldCheckinPlistCount = 6;
// Save to new location
[self.keychain setData:dataInOldLocation
forService:kFIRInstanceIDCheckinKeychainService
- accessibility:NULL
account:self.bundleIdentifierForKeychainAccount
handler:nil];
// Remove from old location
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.h
deleted file mode 100644
index a1aa5e1ad..000000000
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import
-
-@interface FIRInstanceIDKeyPair : NSObject
-
-- (instancetype)init __attribute__((
- unavailable("Use -initWithPrivateKey:publicKey:publicKeyData:privateKeyData: instead.")));
-;
-
-/**
- * Initialize a new 2048 bit RSA keypair. This also stores the keypair in the Keychain
- * Preferences.
- *
- * @param publicKey The publicKey stored in Keychain.
- * @param privateKey The privateKey stored in Keychain.
- * @param publicKeyData The publicKey in NSData format.
- * @param privateKeyData The privateKey in NSData format.
- *
- * @return A new KeyPair instance with the generated public and private key.
- */
-- (instancetype)initWithPrivateKey:(SecKeyRef)privateKey
- publicKey:(SecKeyRef)publicKey
- publicKeyData:(NSData *)publicKeyData
- privateKeyData:(NSData *)privateKeyData NS_DESIGNATED_INITIALIZER;
-
-/**
- * The public key in the RSA 20148 bit generated KeyPair.
- *
- * @return The 2048 bit RSA KeyPair's public key.
- */
-@property(nonatomic, readonly, strong) NSData *publicKeyData;
-
-/**
- * The private key in the RSA 20148 bit generated KeyPair.
- *
- * @return The 2048 bit RSA KeyPair's private key.
- */
-@property(nonatomic, readonly, strong) NSData *privateKeyData;
-
-#pragma mark - Info
-
-/**
- * Checks if the private and public keyPair are valid or not.
- *
- * @return YES if keypair is valid else NO.
- */
-- (BOOL)isValid;
-
-/**
- * The public key in the RSA 2048 bit generated KeyPair.
- *
- * @return The 2048 bit RSA KeyPair's public key.
- */
-- (SecKeyRef)publicKey;
-
-/**
- * The private key in the RSA 2048 bit generated KeyPair.
- *
- * @return The 2048 bit RSA KeyPair's private key.
- */
-- (SecKeyRef)privateKey;
-
-@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.m
deleted file mode 100644
index 52b27c2ef..000000000
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPair.m
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "FIRInstanceIDKeyPair.h"
-
-#import
-
-#import "FIRInstanceIDKeyPairUtilities.h"
-#import "FIRInstanceIDKeychain.h"
-#import "FIRInstanceIDLogger.h"
-#import "NSError+FIRInstanceID.h"
-
-@interface FIRInstanceIDKeyPair () {
- SecKeyRef _privateKey;
- SecKeyRef _publicKey;
-}
-
-@property(nonatomic, readwrite, strong) NSData *publicKeyData;
-@property(nonatomic, readwrite, strong) NSData *privateKeyData;
-@end
-
-@implementation FIRInstanceIDKeyPair
-- (instancetype)initWithPrivateKey:(SecKeyRef)privateKey
- publicKey:(SecKeyRef)publicKey
- publicKeyData:(NSData *)publicKeyData
- privateKeyData:(NSData *)privateKeyData {
- self = [super init];
- if (self) {
- _privateKey = privateKey;
- _publicKey = publicKey;
- _publicKeyData = publicKeyData;
- _privateKeyData = privateKeyData;
- }
- return self;
-}
-
-- (void)dealloc {
- if (_privateKey) {
- CFRelease(_privateKey);
- }
- if (_publicKey) {
- CFRelease(_publicKey);
- }
-}
-
-#pragma mark - Info
-
-- (BOOL)isValid {
- return _privateKey != NULL && _publicKey != NULL;
-}
-
-- (SecKeyRef)publicKey {
- return _publicKey;
-}
-
-- (SecKeyRef)privateKey {
- return _privateKey;
-}
-
-@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.h
deleted file mode 100644
index 02c2896bb..000000000
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import
-
-@class FIRInstanceIDKeyPair;
-
-extern NSString *const kFIRInstanceIDKeyPairSubType;
-
-@class FIRInstanceIDKeyPairStore;
-
-@interface FIRInstanceIDKeyPairStore : NSObject
-
-/**
- * Invalidates the cached keypairs in the Keychain, if needed. The keypair metadata plist is
- * checked for existence. If the plist file does not exist, it is a signal of a new installation,
- * and therefore the key pairs are not valid.
- *
- * Returns YES if keypair has been invalidated.
- */
-- (BOOL)invalidateKeyPairsIfNeeded;
-
-/**
- * Delete the cached RSA keypair from Keychain with the given subtype.
- *
- * @param subtype The subtype used to cache the RSA keypair in Keychain.
- * @param handler The callback handler which is invoked when the keypair deletion is
- * complete, with an error if there is any.
- */
-- (void)deleteSavedKeyPairWithSubtype:(NSString *)subtype handler:(void (^)(NSError *))handler;
-
-/**
- * Delete the plist that caches KeyPair generation timestamps.
- *
- * @param error The error if any while deleting the plist else nil.
- *
- * @return YES if the delete was successful else NO.
- */
-- (BOOL)removeKeyPairCreationTimePlistWithError:(NSError **)error;
-
-/**
- * Loads a cached KeyPair if it exists in the Keychain else generate a new
- * one. If a keyPair already exists in memory this will just return that. This should
- * not be called from the main thread since it could potentially lead to creating a new
- * RSA-2048 bit keyPair which is an expensive operation.
- *
- * @param error The error, if any, while accessing the Keychain.
- *
- * @return A valid 2048 bit RSA key pair.
- */
-- (FIRInstanceIDKeyPair *)loadKeyPairWithError:(NSError **)error;
-
-/**
- * Check if the Keychain has any cached keypairs or not.
- *
- * @return YES if the Keychain has cached RSA KeyPairs else NO.
- */
-- (BOOL)hasCachedKeyPairs;
-
-/**
- * Return an identifier for the app instance. The result is a short identifier that can
- * be used as a key when storing information about the app. This method will return the same
- * ID as long as the application identity remains active. If the identity has been revoked or
- * expired the method will generate and return a new identifier.
- *
- * @param error The error if any while loading the RSA KeyPair.
- *
- * @return The identifier, as url safe string.
- */
-- (NSString *)appIdentityWithError:(NSError *__autoreleasing *)error;
-
-@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.m
deleted file mode 100644
index 48a0d7c53..000000000
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairStore.m
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "FIRInstanceIDKeyPairStore.h"
-
-#import "FIRInstanceIDBackupExcludedPlist.h"
-#import "FIRInstanceIDConstants.h"
-#import "FIRInstanceIDKeyPair.h"
-#import "FIRInstanceIDKeyPairUtilities.h"
-#import "FIRInstanceIDKeychain.h"
-#import "FIRInstanceIDLogger.h"
-#import "FIRInstanceIDUtilities.h"
-#import "NSError+FIRInstanceID.h"
-
-// NOTE: These values should be in sync with what InstanceID saves in as.
-static NSString *const kFIRInstanceIDKeyPairStoreFileName = @"com.google.iid-keypair";
-
-static NSString *const kFIRInstanceIDStoreKeyGenerationTime = @"cre";
-
-static NSString *const kFIRInstanceIDStoreKeyPrefix = @"com.google.iid-";
-static NSString *const kFIRInstanceIDStoreKeyPublic = @"|P|";
-static NSString *const kFIRInstanceIDStoreKeyPrivate = @"|K|";
-static NSString *const kFIRInstanceIDStoreKeySubtype = @"|S|";
-
-static NSString *const kFIRInstanceIDKeyPairPublicTagPrefix = @"com.google.iid.keypair.public-";
-static NSString *const kFIRInstanceIDKeyPairPrivateTagPrefix = @"com.google.iid.keypair.private-";
-
-static const int kMaxMissingEntitlementErrorCount = 3;
-
-NSString *const kFIRInstanceIDKeyPairSubType = @"";
-
-// Query the key with NSData format
-NSData *FIRInstanceIDKeyDataWithTag(NSString *tag) {
- if (![tag length]) {
- return NULL;
- }
- NSDictionary *queryKey = FIRInstanceIDKeyPairQuery(tag, YES, YES);
- CFTypeRef result = [[FIRInstanceIDKeychain sharedInstance] itemWithQuery:queryKey];
- if (!result) {
- return NULL;
- }
- return (__bridge NSData *)result;
-}
-
-// Query the key given a tag
-SecKeyRef FIRInstanceIDCachedKeyRefWithTag(NSString *tag) {
- if (!tag.length) {
- return NULL;
- }
- NSDictionary *queryKey = FIRInstanceIDKeyPairQuery(tag, YES, NO);
- CFTypeRef result = [[FIRInstanceIDKeychain sharedInstance] itemWithQuery:queryKey];
- return (SecKeyRef)result;
-}
-
-// Check if keypair has been migrated from the legacy to the new version
-BOOL FIRInstanceIDHasMigratedKeyPair(NSString *legacyPublicKeyTag, NSString *newPublicKeyTag) {
- NSData *oldPublicKeyData = FIRInstanceIDKeyDataWithTag(legacyPublicKeyTag);
- NSData *newPublicKeyData = FIRInstanceIDKeyDataWithTag(newPublicKeyTag);
- return [oldPublicKeyData isEqualToData:newPublicKeyData];
-}
-
-// The legacy value is hardcoded to be the same key. This is a potential problem in shared keychain
-// environments.
-NSString *FIRInstanceIDLegacyPublicTagWithSubtype(NSString *subtype) {
- NSString *prefix = kFIRInstanceIDStoreKeyPrefix;
- return [NSString stringWithFormat:@"%@%@%@", prefix, subtype, kFIRInstanceIDStoreKeyPublic];
-}
-
-// The legacy value is hardcoded to be the same key. This is a potential problem in shared keychain
-// environments.
-NSString *FIRInstanceIDLegacyPrivateTagWithSubtype(NSString *subtype) {
- NSString *prefix = kFIRInstanceIDStoreKeyPrefix;
- return [NSString stringWithFormat:@"%@%@%@", prefix, subtype, kFIRInstanceIDStoreKeyPrivate];
-}
-
-NSString *FIRInstanceIDPublicTagWithSubtype(NSString *subtype) {
- static NSString *publicTag;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- NSString *mainAppBundleID = FIRInstanceIDAppIdentifier();
- publicTag =
- [NSString stringWithFormat:@"%@%@", kFIRInstanceIDKeyPairPublicTagPrefix, mainAppBundleID];
- });
- return publicTag;
-}
-
-NSString *FIRInstanceIDPrivateTagWithSubtype(NSString *subtype) {
- static NSString *privateTag;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- NSString *mainAppBundleID = FIRInstanceIDAppIdentifier();
- privateTag =
- [NSString stringWithFormat:@"%@%@", kFIRInstanceIDKeyPairPrivateTagPrefix, mainAppBundleID];
- });
- return privateTag;
-}
-
-NSString *FIRInstanceIDCreationTimeKeyWithSubtype(NSString *subtype) {
- return [NSString stringWithFormat:@"%@%@%@", subtype, kFIRInstanceIDStoreKeySubtype,
- kFIRInstanceIDStoreKeyGenerationTime];
-}
-
-@interface FIRInstanceIDKeyPairStore ()
-
-@property(nonatomic, readwrite, strong) FIRInstanceIDBackupExcludedPlist *plist;
-@property(atomic, readwrite, strong) FIRInstanceIDKeyPair *keyPair;
-@property(nonatomic, readwrite, assign) NSInteger keychainEntitlementsErrorCount;
-
-@end
-
-@implementation FIRInstanceIDKeyPairStore
-
-- (instancetype)init {
- self = [super init];
- if (self) {
- NSString *fileName = [[self class] keyStoreFileName];
- _plist =
- [[FIRInstanceIDBackupExcludedPlist alloc] initWithFileName:fileName
- subDirectory:kFIRInstanceIDSubDirectoryName];
- }
- return self;
-}
-
-- (BOOL)invalidateKeyPairsIfNeeded {
- // Currently keypairs are always invalidated if self.plist is missing. This normally indicates
- // a fresh install (or an uninstall/reinstall). In those situations the key pairs should be
- // deleted.
- // NOTE: Although this class refers to multiple key pairs, with different subtypes, in practice
- // only a single subtype is currently supported. (b/64906549)
- if (![self.plist doesFileExist]) {
- // A fresh install, clear all the key pairs in the key chain. Do not perform migration as all
- // key pairs are gone.
- [self deleteSavedKeyPairWithSubtype:kFIRInstanceIDKeyPairSubType handler:nil];
- return YES;
- }
- // Not a fresh install, perform migration at early state.
- [self migrateKeyPairCacheIfNeededWithHandler:nil];
- return NO;
-}
-
-- (BOOL)hasCachedKeyPairs {
- NSError *error;
- if ([self cachedKeyPairWithSubtype:kFIRInstanceIDKeyPairSubType error:&error] == nil) {
- if (error) {
- FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPairStore000,
- @"Failed to get the cached keyPair %@", error);
- }
- error = nil;
- [self removeKeyPairCreationTimePlistWithError:&error];
- if (error) {
- FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPairStore001,
- @"Failed to remove keyPair creationTime plist %@", error);
- }
- return NO;
- }
- return YES;
-}
-
-- (NSString *)appIdentityWithError:(NSError *__autoreleasing *)error {
- // Load the keyPair from Keychain (or generate a key pair, if this is the first run of the app).
- FIRInstanceIDKeyPair *keyPair = [self loadKeyPairWithError:error];
- if (!keyPair) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStoreCouldNotLoadKeyPair,
- @"Keypair could not be loaded from Keychain. Error: %@", (*error));
- return nil;
- }
-
- if (error) {
- *error = nil;
- }
- NSString *appIdentity = FIRInstanceIDAppIdentity(keyPair);
- if (!appIdentity.length) {
- if (error) {
- *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeUnknown];
- }
- }
- return appIdentity;
-}
-
-- (FIRInstanceIDKeyPair *)loadKeyPairWithError:(NSError **)error {
- // In case we call this from different threads we don't want to generate or fetch the
- // keyPair multiple times. Once we have a keyPair in the cache it would mostly be used
- // from there.
- @synchronized(self) {
- if ([self.keyPair isValid]) {
- return self.keyPair;
- }
-
- if (self.keychainEntitlementsErrorCount >= kMaxMissingEntitlementErrorCount) {
- FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPairStore002,
- @"Keychain not accessible, Entitlements missing error (-34018). "
- @"Will not check token in cache.");
- return nil;
- }
-
- if (!self.keyPair) {
- self.keyPair = [self validCachedKeyPairWithSubtype:kFIRInstanceIDKeyPairSubType error:error];
- }
-
- if ((*error).code == kFIRInstanceIDSecMissingEntitlementErrorCode) {
- self.keychainEntitlementsErrorCount++;
- }
-
- if (!self.keyPair) {
- self.keyPair = [self generateAndSaveKeyWithSubtype:kFIRInstanceIDKeyPairSubType
- creationTime:FIRInstanceIDCurrentTimestampInSeconds()
- error:error];
- }
- }
- return self.keyPair;
-}
-
-// TODO(chliangGoogle: Remove subtype support, as it's not being used.
-- (FIRInstanceIDKeyPair *)generateAndSaveKeyWithSubtype:(NSString *)subtype
- creationTime:(int64_t)creationTime
- error:(NSError **)error {
- NSString *publicKeyTag = FIRInstanceIDPublicTagWithSubtype(subtype);
- NSString *privateKeyTag = FIRInstanceIDPrivateTagWithSubtype(subtype);
- FIRInstanceIDKeyPair *keyPair =
- [[FIRInstanceIDKeychain sharedInstance] generateKeyPairWithPrivateTag:privateKeyTag
- publicTag:publicKeyTag];
-
- if (![keyPair isValid]) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore003,
- @"Unable to generate keypair.");
- return nil;
- }
-
- NSString *creationTimeKey = FIRInstanceIDCreationTimeKeyWithSubtype(subtype);
- NSDictionary *keyPairData = @{creationTimeKey : @(creationTime)};
-
- if (error) {
- *error = nil;
- }
- NSMutableDictionary *allKeyPairs = [[self.plist contentAsDictionary] mutableCopy];
- if (allKeyPairs.count) {
- [allKeyPairs addEntriesFromDictionary:keyPairData];
- } else {
- allKeyPairs = [keyPairData mutableCopy];
- }
- if (![self.plist writeDictionary:allKeyPairs error:error]) {
- [FIRInstanceIDKeyPairStore deleteKeyPairWithPrivateTag:privateKeyTag
- publicTag:publicKeyTag
- handler:nil];
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore004,
- @"Failed to save keypair data to plist %@", error ? *error : @"");
- return nil;
- }
-
- return keyPair;
-}
-
-- (FIRInstanceIDKeyPair *)validCachedKeyPairWithSubtype:(NSString *)subtype
- error:(NSError **)error {
- // On a new install (or if the ID was deleted), the plist will be missing, which should trigger
- // a reset of the key pairs in Keychain (if they exist).
- NSDictionary *allKeyPairs = [self.plist contentAsDictionary];
- NSString *creationTimeKey = FIRInstanceIDCreationTimeKeyWithSubtype(subtype);
-
- if (allKeyPairs[creationTimeKey] > 0) {
- return [self cachedKeyPairWithSubtype:subtype error:error];
- } else {
- // There is no need to reset keypair again here as FIRInstanceID init call is always
- // going to be ahead of this call, which already trigger keypair reset if it's new install
- FIRInstanceIDErrorCode code = kFIRInstanceIDErrorCodeInvalidKeyPairCreationTime;
- if (error) {
- *error = [NSError errorWithFIRInstanceIDErrorCode:code];
- }
- return nil;
- }
-}
-
-- (FIRInstanceIDKeyPair *)cachedKeyPairWithSubtype:(NSString *)subtype
- error:(NSError *__autoreleasing *)error {
- // base64 encoded keys
- NSString *publicKeyTag = FIRInstanceIDPublicTagWithSubtype(subtype);
- NSString *privateKeyTag = FIRInstanceIDPrivateTagWithSubtype(subtype);
- return [FIRInstanceIDKeyPairStore keyPairForPrivateKeyTag:privateKeyTag
- publicKeyTag:publicKeyTag
- error:error];
-}
-
-+ (FIRInstanceIDKeyPair *)keyPairForPrivateKeyTag:(NSString *)privateKeyTag
- publicKeyTag:(NSString *)publicKeyTag
- error:(NSError *__autoreleasing *)error {
- if (![privateKeyTag length] || ![publicKeyTag length]) {
- if (error) {
- *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeInvalidKeyPairTags];
- }
- return nil;
- }
-
- SecKeyRef privateKeyRef = FIRInstanceIDCachedKeyRefWithTag(privateKeyTag);
- SecKeyRef publicKeyRef = FIRInstanceIDCachedKeyRefWithTag(publicKeyTag);
-
- if (!privateKeyRef || !publicKeyRef) {
- if (error) {
- *error = [NSError errorWithFIRInstanceIDErrorCode:kFIRInstanceIDErrorCodeMissingKeyPair];
- }
- FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPair000,
- @"No keypair info is found with tag %@", privateKeyTag);
- return nil;
- }
-
- NSData *publicKeyData = FIRInstanceIDKeyDataWithTag(publicKeyTag);
- NSData *privateKeyData = FIRInstanceIDKeyDataWithTag(privateKeyTag);
-
- FIRInstanceIDKeyPair *keyPair = [[FIRInstanceIDKeyPair alloc] initWithPrivateKey:privateKeyRef
- publicKey:publicKeyRef
- publicKeyData:publicKeyData
- privateKeyData:privateKeyData];
- return keyPair;
-}
-
-// Migrates from keypair saved under legacy keys (hardcoded value) to dynamic keys (stable, but
-// unique for the app's bundle id
-- (void)migrateKeyPairCacheIfNeededWithHandler:(void (^)(NSError *error))handler {
- // Attempt to load keypair using legacy keys
- NSString *legacyPublicKeyTag =
- FIRInstanceIDLegacyPublicTagWithSubtype(kFIRInstanceIDKeyPairSubType);
- NSString *legacyPrivateKeyTag =
- FIRInstanceIDLegacyPrivateTagWithSubtype(kFIRInstanceIDKeyPairSubType);
- NSError *error;
- FIRInstanceIDKeyPair *keyPair =
- [FIRInstanceIDKeyPairStore keyPairForPrivateKeyTag:legacyPrivateKeyTag
- publicKeyTag:legacyPublicKeyTag
- error:&error];
- if (![keyPair isValid]) {
- FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeKeyPairNoLegacyKeyPair,
- @"There's no legacy keypair so no need to do migration.");
- if (handler) {
- handler(nil);
- }
- return;
- }
-
- // Check whether migration already done.
- NSString *publicKeyTag = FIRInstanceIDPublicTagWithSubtype(kFIRInstanceIDKeyPairSubType);
- if (FIRInstanceIDHasMigratedKeyPair(legacyPublicKeyTag, publicKeyTag)) {
- if (handler) {
- handler(nil);
- }
- return;
- }
-
- // Also cache locally since we are sure to use the migrated key pair.
- self.keyPair = keyPair;
-
- // Either new key pair doesn't exist or it's different than legacy key pair, start the migration.
- __block NSError *updateKeyRefError;
-
- NSString *privateKeyTag = FIRInstanceIDPrivateTagWithSubtype(kFIRInstanceIDKeyPairSubType);
- [self updateKeyRef:keyPair.publicKey
- withTag:publicKeyTag
- handler:^(NSError *error) {
- if (error) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairMigrationError,
- @"Unable to migrate key pair from legacy ones.");
- updateKeyRefError = error;
- }
- }];
-
- [self updateKeyRef:keyPair.privateKey
- withTag:privateKeyTag
- handler:^(NSError *error) {
- if (error) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairMigrationError,
- @"Unable to migrate key pair from legacy ones.");
- updateKeyRefError = error;
- }
-
- if (handler) {
- handler(updateKeyRefError);
- }
- }];
-}
-
-// Used for migrating from legacy tags to updated tags. The legacy keychain is not deleted for
-// backward compatibility.
-// TODO(chliangGoogle) Delete the legacy keychain when GCM is fully deprecated.
-- (void)updateKeyRef:(SecKeyRef)keyRef
- withTag:(NSString *)tag
- handler:(void (^)(NSError *error))handler {
- NSData *updatedTagData = [tag dataUsingEncoding:NSUTF8StringEncoding];
-
- __block NSError *keychainError;
-
- // Always delete the old keychain before adding a new one to avoid conflicts.
- NSDictionary *deleteQuery = @{
- (__bridge id)kSecAttrApplicationTag : updatedTagData,
- (__bridge id)kSecClass : (__bridge id)kSecClassKey,
- (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeRSA,
- (__bridge id)kSecReturnRef : @(YES),
- };
- [[FIRInstanceIDKeychain sharedInstance] removeItemWithQuery:deleteQuery
- handler:^(NSError *error) {
- if (error) {
- keychainError = error;
- }
- }];
-
- NSDictionary *addQuery = @{
- (__bridge id)kSecAttrApplicationTag : updatedTagData,
- (__bridge id)kSecClass : (__bridge id)kSecClassKey,
- (__bridge id)kSecValueRef : (__bridge id)keyRef,
- (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly,
- };
- [[FIRInstanceIDKeychain sharedInstance] addItemWithQuery:addQuery
- handler:^(NSError *addError) {
- if (addError) {
- keychainError = addError;
- }
-
- if (handler) {
- handler(keychainError);
- }
- }];
-}
-
-- (void)deleteSavedKeyPairWithSubtype:(NSString *)subtype
- handler:(void (^)(NSError *error))handler {
- NSDictionary *allKeyPairs = [self.plist contentAsDictionary];
-
- NSString *publicKeyTag = FIRInstanceIDPublicTagWithSubtype(subtype);
- NSString *privateKeyTag = FIRInstanceIDPrivateTagWithSubtype(subtype);
- NSString *creationTimeKey = FIRInstanceIDCreationTimeKeyWithSubtype(subtype);
-
- // remove the creation time
- if (allKeyPairs[creationTimeKey] > 0) {
- NSMutableDictionary *newKeyPairs = [NSMutableDictionary dictionaryWithDictionary:allKeyPairs];
- [newKeyPairs removeObjectForKey:creationTimeKey];
-
- NSError *plistError;
- if (![self.plist writeDictionary:newKeyPairs error:&plistError]) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore006,
- @"Unable to remove keypair creation time from plist %@", plistError);
- }
- }
-
- self.keyPair = nil;
-
- [FIRInstanceIDKeyPairStore
- deleteKeyPairWithPrivateTag:privateKeyTag
- publicTag:publicKeyTag
- handler:^(NSError *error) {
- // Delete legacy key pairs from GCM/FCM If they exist. All key pairs
- // should be deleted when app is newly installed.
- NSString *legacyPublicKeyTag =
- FIRInstanceIDLegacyPublicTagWithSubtype(subtype);
- NSString *legacyPrivateKeyTag =
- FIRInstanceIDLegacyPrivateTagWithSubtype(subtype);
- [FIRInstanceIDKeyPairStore
- deleteKeyPairWithPrivateTag:legacyPrivateKeyTag
- publicTag:legacyPublicKeyTag
- handler:nil];
- if (error) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore007,
- @"Unable to remove RSA keypair, error: %@",
- error);
- if (handler) {
- handler(error);
- }
- } else {
- if (handler) {
- handler(nil);
- }
- }
- }];
-}
-
-+ (void)deleteKeyPairWithPrivateTag:(NSString *)privateTag
- publicTag:(NSString *)publicTag
- handler:(void (^)(NSError *))handler {
- NSDictionary *queryPublicKey = FIRInstanceIDKeyPairQuery(publicTag, NO, NO);
- NSDictionary *queryPrivateKey = FIRInstanceIDKeyPairQuery(privateTag, NO, NO);
-
- __block NSError *keychainError;
-
- // Always remove public key first because it is the key we generate IID.
- [[FIRInstanceIDKeychain sharedInstance] removeItemWithQuery:queryPublicKey
- handler:^(NSError *error) {
- if (error) {
- keychainError = error;
- }
- }];
-
- [[FIRInstanceIDKeychain sharedInstance] removeItemWithQuery:queryPrivateKey
- handler:^(NSError *error) {
- if (error) {
- keychainError = error;
- }
-
- if (handler) {
- handler(keychainError);
- }
- }];
-}
-
-- (BOOL)removeKeyPairCreationTimePlistWithError:(NSError *__autoreleasing *)error {
- if (![self.plist deleteFile:error]) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPairStore008,
- @"Unable to delete keypair creation times plist");
- return NO;
- }
- return YES;
-}
-
-+ (NSString *)keyStoreFileName {
- return kFIRInstanceIDKeyPairStoreFileName;
-}
-
-@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.h
deleted file mode 100644
index b8baa6af2..000000000
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import
-
-@class FIRInstanceIDKeyPair;
-
-/**
- * A web-safe base64 encoded string with no padding.
- *
- * @param data The data to encode.
- *
- * @return A web-safe base 64 encoded string with no padding.
- */
-FOUNDATION_EXPORT NSString *FIRInstanceIDWebSafeBase64(NSData *data);
-
-FOUNDATION_EXPORT NSData *FIRInstanceIDSHA1(NSData *data);
-
-FOUNDATION_EXPORT NSDictionary *FIRInstanceIDKeyPairQuery(NSString *tag,
- BOOL addReturnAttr,
- BOOL returnData);
-
-FOUNDATION_EXPORT NSString *FIRInstanceIDAppIdentity(FIRInstanceIDKeyPair *keyPair);
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.m
deleted file mode 100644
index 021d94b68..000000000
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeyPairUtilities.m
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "FIRInstanceIDKeyPairUtilities.h"
-
-#import
-
-#import "FIRInstanceIDKeyPair.h"
-#import "FIRInstanceIDLogger.h"
-#import "FIRInstanceIDStringEncoding.h"
-
-NSString *FIRInstanceIDWebSafeBase64(NSData *data) {
- // Websafe encoding with no padding.
- FIRInstanceIDStringEncoding *encoding =
- [FIRInstanceIDStringEncoding rfc4648Base64WebsafeStringEncoding];
- [encoding setDoPad:NO];
- return [encoding encode:data];
-}
-
-NSData *FIRInstanceIDSHA1(NSData *data) {
- unsigned int outputLength = CC_SHA1_DIGEST_LENGTH;
- unsigned char output[outputLength];
- unsigned int length = (unsigned int)[data length];
-
- CC_SHA1(data.bytes, length, output);
- return [NSMutableData dataWithBytes:output length:outputLength];
-}
-
-NSDictionary *FIRInstanceIDKeyPairQuery(NSString *tag, BOOL addReturnAttr, BOOL returnData) {
- NSMutableDictionary *queryKey = [NSMutableDictionary dictionary];
- NSData *tagData = [tag dataUsingEncoding:NSUTF8StringEncoding];
-
- queryKey[(__bridge id)kSecClass] = (__bridge id)kSecClassKey;
- queryKey[(__bridge id)kSecAttrApplicationTag] = tagData;
- queryKey[(__bridge id)kSecAttrKeyType] = (__bridge id)kSecAttrKeyTypeRSA;
- if (addReturnAttr) {
- if (returnData) {
- queryKey[(__bridge id)kSecReturnData] = @(YES);
- } else {
- queryKey[(__bridge id)kSecReturnRef] = @(YES);
- }
- }
- return queryKey;
-}
-
-NSString *FIRInstanceIDAppIdentity(FIRInstanceIDKeyPair *keyPair) {
- // An Instance-ID is a 64 bit (8 byte) integer with a fixed 4-bit header of 0111 (=^ 0x7).
- // The variable 60 bits are obtained by truncating the SHA1 of the app-instance's public key.
- SecKeyRef publicKeyRef = [keyPair publicKey];
- if (!publicKeyRef) {
- FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeKeyPair002,
- @"Unable to create a valid asymmetric crypto key");
- return nil;
- }
- NSData *publicKeyData = keyPair.publicKeyData;
- NSData *publicKeySHA1 = FIRInstanceIDSHA1(publicKeyData);
-
- const uint8_t *bytes = publicKeySHA1.bytes;
- NSMutableData *identityData = [NSMutableData dataWithData:publicKeySHA1];
-
- uint8_t b0 = bytes[0];
- // Take the first byte and make the initial four 7 by initially making the initial 4 bits 0
- // and then adding 0x70 to it.
- b0 = 0x70 + (0xF & b0);
- // failsafe should give you back b0 itself
- b0 = (b0 & 0xFF);
- [identityData replaceBytesInRange:NSMakeRange(0, 1) withBytes:&b0];
- NSData *data = [identityData subdataWithRange:NSMakeRange(0, 8 * sizeof(Byte))];
- return FIRInstanceIDWebSafeBase64(data);
-}
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h
index 0bd2a4933..1c80d8e34 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.h
@@ -19,8 +19,6 @@
/* The Keychain error domain */
extern NSString *const kFIRInstanceIDKeychainErrorDomain;
-@class FIRInstanceIDKeyPair;
-
/*
* Wrapping the keychain operations in a serialize queue. This is to avoid keychain operation
* blocking main queue.
@@ -61,16 +59,4 @@ extern NSString *const kFIRInstanceIDKeychainErrorDomain;
*/
- (void)addItemWithQuery:(NSDictionary *)keychainQuery handler:(void (^)(NSError *))handler;
-#pragma mark - Keypair
-/**
- * Generate a public/private key pair given their tags.
- *
- * @param privateTag The private tag associated with the private key.
- * @param publicTag The public tag associated with the public key.
- *
- * @return A new FIRInstanceIDKeyPair object.
- */
-- (FIRInstanceIDKeyPair *)generateKeyPairWithPrivateTag:(NSString *)privateTag
- publicTag:(NSString *)publicTag;
-
@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m
index 81c73727e..df1b4f763 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDKeychain.m
@@ -16,14 +16,10 @@
#import "FIRInstanceIDKeychain.h"
-#import "FIRInstanceIDKeyPair.h"
-#import "FIRInstanceIDKeyPairUtilities.h"
#import "FIRInstanceIDLogger.h"
NSString *const kFIRInstanceIDKeychainErrorDomain = @"com.google.iid";
-static const NSUInteger kRSA2048KeyPairSize = 2048;
-
@interface FIRInstanceIDKeychain () {
dispatch_queue_t _keychainOperationQueue;
}
@@ -115,60 +111,4 @@ static const NSUInteger kRSA2048KeyPairSize = 2048;
});
}
-- (FIRInstanceIDKeyPair *)generateKeyPairWithPrivateTag:(NSString *)privateTag
- publicTag:(NSString *)publicTag {
- // TODO(chliangGoogle) this is called by appInstanceID, which is an internal API used by other
- // Firebase teams, will see if we can make it async.
- NSData *publicTagData = [publicTag dataUsingEncoding:NSUTF8StringEncoding];
- NSData *privateTagData = [privateTag dataUsingEncoding:NSUTF8StringEncoding];
-
- NSDictionary *privateKeyAttr = @{
- (__bridge id)kSecAttrIsPermanent : @YES,
- (__bridge id)kSecAttrApplicationTag : privateTagData,
- (__bridge id)kSecAttrLabel : @"Firebase InstanceID Key Pair Private Key",
- (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly,
- };
-
- NSDictionary *publicKeyAttr = @{
- (__bridge id)kSecAttrIsPermanent : @YES,
- (__bridge id)kSecAttrApplicationTag : publicTagData,
- (__bridge id)kSecAttrLabel : @"Firebase InstanceID Key Pair Public Key",
- (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly,
- };
-
- NSDictionary *keyPairAttributes = @{
- (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeRSA,
- (__bridge id)kSecAttrLabel : @"Firebase InstanceID Key Pair",
- (__bridge id)kSecAttrKeySizeInBits : @(kRSA2048KeyPairSize),
- (__bridge id)kSecPrivateKeyAttrs : privateKeyAttr,
- (__bridge id)kSecPublicKeyAttrs : publicKeyAttr,
- };
-
- __block SecKeyRef privateKey = NULL;
- __block SecKeyRef publicKey = NULL;
- dispatch_sync(_keychainOperationQueue, ^{
- // SecKeyGeneratePair does not allow you to set kSetAttrAccessible on the keys. We need the keys
- // to be accessible even when the device is locked (i.e. app is woken up during a push
- // notification, or some background refresh).
- OSStatus status =
- SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttributes, &publicKey, &privateKey);
- if (status != noErr || publicKey == NULL || privateKey == NULL) {
- FIRInstanceIDLoggerWarning(kFIRInstanceIDKeychainCreateKeyPairError,
- @"Couldn't create keypair from Keychain OSStatus: %d",
- (int)status);
- }
- });
- // Extract the actual public and private key data from the Keychain
- NSDictionary *publicKeyDataQuery = FIRInstanceIDKeyPairQuery(publicTag, YES, YES);
- NSDictionary *privateKeyDataQuery = FIRInstanceIDKeyPairQuery(privateTag, YES, YES);
-
- NSData *publicKeyData = (__bridge NSData *)[self itemWithQuery:publicKeyDataQuery];
- NSData *privateKeyData = (__bridge NSData *)[self itemWithQuery:privateKeyDataQuery];
-
- return [[FIRInstanceIDKeyPair alloc] initWithPrivateKey:privateKey
- publicKey:publicKey
- publicKeyData:publicKeyData
- privateKeyData:privateKeyData];
-}
-
@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h
index 58368d041..b6723fda0 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.h
@@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithAuthorizedEntity:(nullable NSString *)authorizedEntity
scope:(nullable NSString *)scope
checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences
- keyPair:(nullable FIRInstanceIDKeyPair *)keyPair
+ instanceID:(nullable NSString *)instanceID
action:(FIRInstanceIDTokenAction)action;
@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m
index 365f321bd..34511c434 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenDeleteOperation.m
@@ -29,23 +29,21 @@
- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity
scope:(NSString *)scope
checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences
- keyPair:(FIRInstanceIDKeyPair *)keyPair
+ instanceID:(NSString *)instanceID
action:(FIRInstanceIDTokenAction)action {
self = [super initWithAction:action
forAuthorizedEntity:authorizedEntity
scope:scope
options:nil
checkinPreferences:checkinPreferences
- keyPair:keyPair];
+ instanceID:instanceID];
if (self) {
}
return self;
}
- (void)performTokenOperation {
- NSString *authHeader =
- [FIRInstanceIDTokenOperation HTTPAuthHeaderFromCheckin:self.checkinPreferences];
- NSMutableURLRequest *request = [FIRInstanceIDTokenOperation requestWithAuthHeader:authHeader];
+ NSMutableURLRequest *request = [self tokenRequest];
// Build form-encoded body
NSString *deviceAuthID = self.checkinPreferences.deviceID;
@@ -62,8 +60,8 @@
}
// Typically we include our public key-signed url items, but in some cases (like deleting all FCM
// tokens), we don't.
- if (self.keyPair != nil) {
- [queryItems addObjectsFromArray:[self queryItemsWithKeyPair:self.keyPair]];
+ if (self.instanceID.length > 0) {
+ [queryItems addObjectsFromArray:[self queryItemsWithInstanceID:self.instanceID]];
}
NSString *content = FIRInstanceIDQueryFromQueryItems(queryItems);
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h
index 87be60fc0..6fa800eff 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.h
@@ -20,13 +20,15 @@ NS_ASSUME_NONNULL_BEGIN
FOUNDATION_EXPORT NSString *const kFIRInstanceIDFirebaseUserAgentKey;
+FOUNDATION_EXPORT NSString *const kFIRInstanceIDFirebaseHeartbeatKey;
+
@interface FIRInstanceIDTokenFetchOperation : FIRInstanceIDTokenOperation
- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity
scope:(NSString *)scope
options:(nullable NSDictionary *)options
checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences
- keyPair:(FIRInstanceIDKeyPair *)keyPair;
+ instanceID:(NSString *)instanceID;
@end
NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m
index 0689b3fba..bdc87014f 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenFetchOperation.m
@@ -26,6 +26,7 @@
#import "NSError+FIRInstanceID.h"
#import
+#import
// We can have a static int since this error should theoretically only
// happen once (for the first time). If it repeats there is something
@@ -33,6 +34,8 @@
static int phoneRegistrationErrorRetryCount = 0;
static const int kMaxPhoneRegistrationErrorRetryCount = 10;
NSString *const kFIRInstanceIDFirebaseUserAgentKey = @"X-firebase-client";
+NSString *const kFIRInstanceIDFirebaseHeartbeatKey = @"X-firebase-client-log-type";
+NSString *const kFIRInstanceIDHeartbeatTag = @"fire-iid";
@implementation FIRInstanceIDTokenFetchOperation
@@ -40,26 +43,26 @@ NSString *const kFIRInstanceIDFirebaseUserAgentKey = @"X-firebase-client";
scope:(NSString *)scope
options:(nullable NSDictionary *)options
checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences
- keyPair:(FIRInstanceIDKeyPair *)keyPair {
+ instanceID:(NSString *)instanceID {
self = [super initWithAction:FIRInstanceIDTokenActionFetch
forAuthorizedEntity:authorizedEntity
scope:scope
options:options
checkinPreferences:checkinPreferences
- keyPair:keyPair];
+ instanceID:instanceID];
if (self) {
}
return self;
}
- (void)performTokenOperation {
- NSString *authHeader =
- [FIRInstanceIDTokenOperation HTTPAuthHeaderFromCheckin:self.checkinPreferences];
- NSMutableURLRequest *request = [[self class] requestWithAuthHeader:authHeader];
+ NSMutableURLRequest *request = [self tokenRequest];
NSString *checkinVersionInfo = self.checkinPreferences.versionInfo;
[request setValue:checkinVersionInfo forHTTPHeaderField:@"info"];
[request setValue:[FIRApp firebaseUserAgent]
forHTTPHeaderField:kFIRInstanceIDFirebaseUserAgentKey];
+ [request setValue:@([FIRHeartbeatInfo heartbeatCodeForTag:kFIRInstanceIDHeartbeatTag]).stringValue
+ forHTTPHeaderField:kFIRInstanceIDFirebaseHeartbeatKey];
// Build form-encoded body
NSString *deviceAuthID = self.checkinPreferences.deviceID;
@@ -70,7 +73,7 @@ NSString *const kFIRInstanceIDFirebaseUserAgentKey = @"X-firebase-client";
[queryItems addObject:[FIRInstanceIDURLQueryItem queryItemWithName:@"X-subtype"
value:self.authorizedEntity]];
- [queryItems addObjectsFromArray:[self queryItemsWithKeyPair:self.keyPair]];
+ [queryItems addObjectsFromArray:[self queryItemsWithInstanceID:self.instanceID]];
// Create query items from passed-in options
id apnsTokenData = self.options[kFIRInstanceIDTokenOptionsAPNSKey];
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h
index 34ad71662..3b752a3aa 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.h
@@ -74,8 +74,18 @@ NS_ASSUME_NONNULL_BEGIN
* 2. Language setting is not changed.
* 3. App version is current.
* 4. GMP App ID is current.
+ * 5. token is consistent with the current IID.
+ * 6. APNS info has changed.
+ * @param IID The app identifiier that is used to check if token is prefixed with.
+ * @return If token is fresh.
+ *
*/
-- (BOOL)isFresh;
+- (BOOL)isFreshWithIID:(NSString *)IID;
+
+/*
+ * Check whether the token is default token.
+ */
+- (BOOL)isDefaultToken;
@end
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m
index 5bb0017d8..59b0e9240 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenInfo.m
@@ -16,6 +16,7 @@
#import "FIRInstanceIDTokenInfo.h"
+#import "FIRInstanceIDConstants.h"
#import "FIRInstanceIDLogger.h"
#import "FIRInstanceIDUtilities.h"
@@ -65,13 +66,21 @@ const NSTimeInterval kDefaultFetchTokenInterval = 7 * 24 * 60 * 60; // 7 days.
return self;
}
-- (BOOL)isFresh {
+- (BOOL)isFreshWithIID:(NSString *)IID {
// Last fetch token cache time could be null if token is from legacy storage format. Then token is
// considered not fresh and should be refreshed and overwrite with the latest storage format.
+ if (!IID) {
+ return NO;
+ }
if (!_cacheTime) {
return NO;
}
+ // Check if it's consistent with IID
+ if (![self.token hasPrefix:IID]) {
+ return NO;
+ }
+
// Check if app has just been updated to a new version.
NSString *currentAppVersion = FIRInstanceIDCurrentAppVersion();
if (!_appVersion || ![_appVersion isEqualToString:currentAppVersion]) {
@@ -105,6 +114,11 @@ const NSTimeInterval kDefaultFetchTokenInterval = 7 * 24 * 60 * 60; // 7 days.
NSTimeInterval timeSinceLastFetchToken = currentTimestamp - lastFetchTokenTimestamp;
return (timeSinceLastFetchToken < kDefaultFetchTokenInterval);
}
+
+- (BOOL)isDefaultToken {
+ return [self.scope isEqualToString:kFIRInstanceIDDefaultTokenScope];
+}
+
#pragma mark - NSCoding
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h
index 491b99c4a..46e1ac887 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.h
@@ -18,7 +18,6 @@
@class FIRInstanceIDAuthService;
@class FIRInstanceIDCheckinPreferences;
-@class FIRInstanceIDKeyPair;
@class FIRInstanceIDTokenInfo;
@class FIRInstanceIDStore;
@@ -46,7 +45,7 @@ typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) {
*
* @param authorizedEntity The authorized entity for the token, should not be nil.
* @param scope The scope for the token, should not be nil.
- * @param keyPair The keyPair that represents the app identity.
+ * @param instanceID The unique string identifying the app instance.
* @param options The options to be added to the fetch request.
* @param handler The handler to be invoked once we have the token or the
* fetch request to InstanceID backend results in an error. Also
@@ -55,7 +54,7 @@ typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) {
*/
- (void)fetchNewTokenWithAuthorizedEntity:(NSString *)authorizedEntity
scope:(NSString *)scope
- keyPair:(FIRInstanceIDKeyPair *)keyPair
+ instanceID:(NSString *)instanceID
options:(NSDictionary *)options
handler:(FIRInstanceIDTokenHandler)handler;
@@ -77,7 +76,7 @@ typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) {
*
* @param authorizedEntity The authorized entity for the token, should not be nil.
* @param scope The scope for the token, should not be nil.
- * @param keyPair The keyPair that represents the app identity.
+ * @param instanceID The unique string identifying the app instance.
* @param handler The handler to be invoked once the delete request to
* InstanceID backend has returned. If the request was
* successful we invoke the handler with a nil error;
@@ -87,21 +86,21 @@ typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) {
*/
- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity
scope:(NSString *)scope
- keyPair:(FIRInstanceIDKeyPair *)keyPair
+ instanceID:(NSString *)instanceID
handler:(FIRInstanceIDDeleteTokenHandler)handler;
/**
* Deletes all cached tokens from the persistent store. This method should only be triggered
* when InstanceID is deleted
*
- * @param keyPair The keyPair for the given app.
- * @param handler The handler to be invoked once the delete request to InstanceID backend
- * has returned. If the request was successful we invoke the handler with
- * a nil error; else we pass in an appropriate error. This should be non-nil
- * and be called asynchronously.
+ * @param instanceID The unique string identifying the app instance.
+ * @param handler The handler to be invoked once the delete request to InstanceID backend
+ * has returned. If the request was successful we invoke the handler with
+ * a nil error; else we pass in an appropriate error. This should be non-nil
+ * and be called asynchronously.
*/
-- (void)deleteAllTokensWithKeyPair:(FIRInstanceIDKeyPair *)keyPair
- handler:(FIRInstanceIDDeleteHandler)handler;
+- (void)deleteAllTokensWithInstanceID:(NSString *)instanceID
+ handler:(FIRInstanceIDDeleteHandler)handler;
/**
* Deletes all cached tokens from the persistent store.
@@ -121,13 +120,14 @@ typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) {
/**
* Invalidate any cached tokens, if the app version has changed since last launch or if the token
* is cached for more than 7 days.
+ * @param IID The cached instanceID, check if token is prefixed by such IID.
*
* @return Whether we should fetch default token from server.
*
* @discussion This should safely be called prior to any tokens being retrieved from
* the cache or being fetched from the network.
*/
-- (BOOL)checkForTokenRefreshPolicy;
+- (BOOL)checkTokenRefreshPolicyWithIID:(NSString *)IID;
/**
* Upon being provided with different APNs or sandbox, any locally cached tokens
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m
index 0c4f644f3..0ebcfc889 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenManager.m
@@ -71,7 +71,7 @@
- (void)fetchNewTokenWithAuthorizedEntity:(NSString *)authorizedEntity
scope:(NSString *)scope
- keyPair:(FIRInstanceIDKeyPair *)keyPair
+ instanceID:(NSString *)instanceID
options:(NSDictionary *)options
handler:(FIRInstanceIDTokenHandler)handler {
FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeTokenManager000,
@@ -81,7 +81,7 @@
[self createFetchOperationWithAuthorizedEntity:authorizedEntity
scope:scope
options:options
- keyPair:keyPair];
+ instanceID:instanceID];
FIRInstanceID_WEAKIFY(self);
FIRInstanceIDTokenOperationCompletion completion =
^(FIRInstanceIDTokenOperationResult result, NSString *_Nullable token,
@@ -143,7 +143,7 @@
- (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity
scope:(NSString *)scope
- keyPair:(FIRInstanceIDKeyPair *)keyPair
+ instanceID:(NSString *)instanceID
handler:(FIRInstanceIDDeleteTokenHandler)handler {
if ([self.instanceIDStore tokenInfoWithAuthorizedEntity:authorizedEntity scope:scope]) {
[self.instanceIDStore removeCachedTokenWithAuthorizedEntity:authorizedEntity scope:scope];
@@ -155,7 +155,7 @@
[self createDeleteOperationWithAuthorizedEntity:authorizedEntity
scope:scope
checkinPreferences:checkinPreferences
- keyPair:keyPair
+ instanceID:instanceID
action:FIRInstanceIDTokenActionDeleteToken];
if (handler) {
@@ -169,8 +169,8 @@
[self.tokenOperations addOperation:operation];
}
-- (void)deleteAllTokensWithKeyPair:(FIRInstanceIDKeyPair *)keyPair
- handler:(FIRInstanceIDDeleteHandler)handler {
+- (void)deleteAllTokensWithInstanceID:(NSString *)instanceID
+ handler:(FIRInstanceIDDeleteHandler)handler {
// delete all tokens
FIRInstanceIDCheckinPreferences *checkinPreferences = self.authService.checkinPreferences;
if (!checkinPreferences) {
@@ -185,7 +185,7 @@
[self createDeleteOperationWithAuthorizedEntity:kFIRInstanceIDKeychainWildcardIdentifier
scope:kFIRInstanceIDKeychainWildcardIdentifier
checkinPreferences:checkinPreferences
- keyPair:keyPair
+ instanceID:instanceID
action:FIRInstanceIDTokenActionDeleteTokenAndIID];
if (handler) {
[operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result,
@@ -222,7 +222,7 @@
[self createDeleteOperationWithAuthorizedEntity:nil
scope:nil
checkinPreferences:checkin
- keyPair:nil
+ instanceID:nil
action:FIRInstanceIDTokenActionDeleteToken];
[operation addCompletionHandler:^(FIRInstanceIDTokenOperationResult result,
NSString *_Nullable token, NSError *_Nullable error) {
@@ -245,14 +245,14 @@
createFetchOperationWithAuthorizedEntity:(NSString *)authorizedEntity
scope:(NSString *)scope
options:(NSDictionary *)options
- keyPair:(FIRInstanceIDKeyPair *)keyPair {
+ instanceID:(NSString *)instanceID {
FIRInstanceIDCheckinPreferences *checkinPreferences = self.authService.checkinPreferences;
FIRInstanceIDTokenFetchOperation *operation =
[[FIRInstanceIDTokenFetchOperation alloc] initWithAuthorizedEntity:authorizedEntity
scope:scope
options:options
checkinPreferences:checkinPreferences
- keyPair:keyPair];
+ instanceID:instanceID];
return operation;
}
@@ -261,19 +261,19 @@
createDeleteOperationWithAuthorizedEntity:(NSString *)authorizedEntity
scope:(NSString *)scope
checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences
- keyPair:(FIRInstanceIDKeyPair *)keyPair
+ instanceID:(NSString *)instanceID
action:(FIRInstanceIDTokenAction)action {
FIRInstanceIDTokenDeleteOperation *operation =
[[FIRInstanceIDTokenDeleteOperation alloc] initWithAuthorizedEntity:authorizedEntity
scope:scope
checkinPreferences:checkinPreferences
- keyPair:keyPair
+ instanceID:instanceID
action:action];
return operation;
}
#pragma mark - Invalidating Cached Tokens
-- (BOOL)checkForTokenRefreshPolicy {
+- (BOOL)checkTokenRefreshPolicyWithIID:(NSString *)IID {
// We know at least one cached token exists.
BOOL shouldFetchDefaultToken = NO;
NSArray *tokenInfos = [self.instanceIDStore cachedTokenInfos];
@@ -281,12 +281,11 @@
NSMutableArray *tokenInfosToDelete =
[NSMutableArray arrayWithCapacity:tokenInfos.count];
for (FIRInstanceIDTokenInfo *tokenInfo in tokenInfos) {
- BOOL isTokenFresh = [tokenInfo isFresh];
- if (isTokenFresh) {
- // Token is fresh, do nothing.
+ if ([tokenInfo isFreshWithIID:IID]) {
+ // Token is fresh and in right format, do nothing
continue;
}
- if ([tokenInfo.scope isEqualToString:kFIRInstanceIDDefaultTokenScope]) {
+ if ([tokenInfo isDefaultToken]) {
// Default token is expired, do not mark for deletion. Fetch directly from server to
// replace the current one.
shouldFetchDefaultToken = YES;
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h
index 68d9db183..338387577 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation+Private.h
@@ -18,7 +18,6 @@
#import "FIRInstanceIDUtilities.h"
-@class FIRInstanceIDKeyPair;
@class FIRInstanceIDURLQueryItem;
NS_ASSUME_NONNULL_BEGIN
@@ -40,13 +39,13 @@ NS_ASSUME_NONNULL_BEGIN
scope:(NSString *)scope
options:(nullable NSDictionary *)options
checkinPreferences:(FIRInstanceIDCheckinPreferences *)checkinPreferences
- keyPair:(FIRInstanceIDKeyPair *)keyPair;
+ instanceID:(NSString *)instanceID;
#pragma mark - Request Construction
-+ (NSMutableURLRequest *)requestWithAuthHeader:(NSString *)authHeaderString;
+ (NSMutableArray *)standardQueryItemsWithDeviceID:(NSString *)deviceID
scope:(NSString *)scope;
-- (NSArray *)queryItemsWithKeyPair:(FIRInstanceIDKeyPair *)keyPair;
+- (NSMutableURLRequest *)tokenRequest;
+- (NSArray *)queryItemsWithInstanceID:(NSString *)instanceID;
#pragma mark - HTTP Headers
/**
@@ -62,6 +61,9 @@ NS_ASSUME_NONNULL_BEGIN
token:(nullable NSString *)token
error:(nullable NSError *)error;
+#pragma mark - Methods to override
+- (void)performTokenOperation;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h
index 1a1842cf2..fa8ad085b 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.h
@@ -16,7 +16,6 @@
#import
-@class FIRInstanceIDKeyPair;
@class FIRInstanceIDCheckinPreferences;
NS_ASSUME_NONNULL_BEGIN
@@ -60,7 +59,7 @@ typedef void (^FIRInstanceIDTokenOperationCompletion)(FIRInstanceIDTokenOperatio
@property(nonatomic, readonly, nullable) NSString *scope;
@property(nonatomic, readonly, nullable) NSDictionary *options;
@property(nonatomic, readonly, strong) FIRInstanceIDCheckinPreferences *checkinPreferences;
-@property(nonatomic, readonly, strong) FIRInstanceIDKeyPair *keyPair;
+@property(nonatomic, readonly, strong) NSString *instanceID;
@property(nonatomic, readonly) FIRInstanceIDTokenOperationResult result;
diff --git a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m
index 5c20f3cec..aa0f75e07 100644
--- a/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m
+++ b/ios/Pods/FirebaseInstanceID/Firebase/InstanceID/FIRInstanceIDTokenOperation.m
@@ -16,9 +16,9 @@
#import "FIRInstanceIDTokenOperation.h"
+#import
+
#import "FIRInstanceIDCheckinPreferences.h"
-#import "FIRInstanceIDKeyPair.h"
-#import "FIRInstanceIDKeyPairUtilities.h"
#import "FIRInstanceIDLogger.h"
#import "FIRInstanceIDURLQueryItem.h"
#import "FIRInstanceIDUtilities.h"
@@ -38,12 +38,14 @@ static NSString *const kFIRInstanceIDParamFCMLibVersion = @"X-cliv";
}
@property(nonatomic, readwrite, strong) FIRInstanceIDCheckinPreferences *checkinPreferences;
-@property(nonatomic, readwrite, strong) FIRInstanceIDKeyPair *keyPair;
+@property(nonatomic, readwrite, strong) NSString *instanceID;
@property(atomic, strong) NSURLSessionDataTask *dataTask;
@property(readonly, strong)
NSMutableArray