From 046fc8650cc5462ee234f3868834248ca64658bf Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Tue, 7 Sep 2021 14:13:28 -0400 Subject: [PATCH 01/11] RTDB SwiftUI: add App Check dependency --- .../DatabaseExample.xcodeproj/project.pbxproj | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj index 4a3f4ad9d..32888777e 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 9A0FAF2F26E7CFD10092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF2E26E7CFD10092BADD /* FirebaseAppCheck */; }; + 9A0FAF3126E7D1310092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF3026E7D1310092BADD /* FirebaseAppCheck */; }; + 9A0FAF3326E7D1380092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF3226E7D1380092BADD /* FirebaseAppCheck */; }; B9029EF126A10B1500C92F12 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9029EF026A10B1500C92F12 /* GoogleService-Info.plist */; }; C70B63FF2696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; C70B64002696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; @@ -154,6 +157,7 @@ buildActionMask = 2147483647; files = ( C796F2C526D228F30076C5F5 /* FirebaseDatabase in Frameworks */, + 9A0FAF3326E7D1380092BADD /* FirebaseAppCheck in Frameworks */, C796F2C326D228F30076C5F5 /* FirebaseAuth in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -162,6 +166,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 9A0FAF2F26E7CFD10092BADD /* FirebaseAppCheck in Frameworks */, C7C6B59B268C8D7800546A57 /* FirebaseDatabase in Frameworks */, C7C6B597268C8D7800546A57 /* FirebaseDatabaseSwift-Beta in Frameworks */, C7C6B599268C8D7800546A57 /* FirebaseAuth in Frameworks */, @@ -173,6 +178,7 @@ buildActionMask = 2147483647; files = ( C796F29A26CCDCF50076C5F5 /* FirebaseDatabase in Frameworks */, + 9A0FAF3126E7D1310092BADD /* FirebaseAppCheck in Frameworks */, C796F29826CCDCEF0076C5F5 /* FirebaseAuth in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -360,6 +366,7 @@ packageProductDependencies = ( C796F2C226D228F30076C5F5 /* FirebaseAuth */, C796F2C426D228F30076C5F5 /* FirebaseDatabase */, + 9A0FAF3226E7D1380092BADD /* FirebaseAppCheck */, ); productName = tvOSDatabaseExample; productReference = C796F2A326D228180076C5F5 /* DatabaseExample (tvOS).app */; @@ -382,6 +389,7 @@ C7C6B596268C8D7800546A57 /* FirebaseDatabaseSwift-Beta */, C7C6B598268C8D7800546A57 /* FirebaseAuth */, C7C6B59A268C8D7800546A57 /* FirebaseDatabase */, + 9A0FAF2E26E7CFD10092BADD /* FirebaseAppCheck */, ); productName = "DatabaseExample (iOS)"; productReference = C7C6B57B268C8C9C00546A57 /* DatabaseExample.app */; @@ -403,6 +411,7 @@ packageProductDependencies = ( C796F29726CCDCEF0076C5F5 /* FirebaseAuth */, C796F29926CCDCF50076C5F5 /* FirebaseDatabase */, + 9A0FAF3026E7D1310092BADD /* FirebaseAppCheck */, ); productName = "DatabaseExample (macOS)"; productReference = C7C6B583268C8C9C00546A57 /* DatabaseExample.app */; @@ -1117,6 +1126,21 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 9A0FAF2E26E7CFD10092BADD /* FirebaseAppCheck */ = { + isa = XCSwiftPackageProductDependency; + package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAppCheck; + }; + 9A0FAF3026E7D1310092BADD /* FirebaseAppCheck */ = { + isa = XCSwiftPackageProductDependency; + package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAppCheck; + }; + 9A0FAF3226E7D1380092BADD /* FirebaseAppCheck */ = { + isa = XCSwiftPackageProductDependency; + package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAppCheck; + }; C796F29726CCDCEF0076C5F5 /* FirebaseAuth */ = { isa = XCSwiftPackageProductDependency; package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; From 44ce6ee3055061b03603aba4e2b6f78ac05e69c6 Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Tue, 7 Sep 2021 15:26:46 -0400 Subject: [PATCH 02/11] Create and install a simple App Check provider factory --- .../DatabaseExample.xcodeproj/project.pbxproj | 16 ++++++++++ .../AppCheck/AppCheckProviderFactory.swift | 31 +++++++++++++++++++ .../Shared/DatabaseExampleApp.swift | 3 ++ 3 files changed, 50 insertions(+) create mode 100644 database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj index 32888777e..85447d1c5 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj @@ -10,6 +10,9 @@ 9A0FAF2F26E7CFD10092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF2E26E7CFD10092BADD /* FirebaseAppCheck */; }; 9A0FAF3126E7D1310092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF3026E7D1310092BADD /* FirebaseAppCheck */; }; 9A0FAF3326E7D1380092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF3226E7D1380092BADD /* FirebaseAppCheck */; }; + 9A0FAF3626E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; + 9A0FAF3726E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; + 9A0FAF3826E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; B9029EF126A10B1500C92F12 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9029EF026A10B1500C92F12 /* GoogleService-Info.plist */; }; C70B63FF2696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; C70B64002696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; @@ -99,6 +102,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCheckProviderFactory.swift; sourceTree = ""; }; B9029EF026A10B1500C92F12 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; C70B63FE2696B29400851A91 /* NewPostsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostsView.swift; sourceTree = ""; }; C730A31E26B0998A00A29E81 /* PostsType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostsType.swift; sourceTree = ""; }; @@ -186,6 +190,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 9A0FAF3426E7E37E0092BADD /* AppCheck */ = { + isa = PBXGroup; + children = ( + 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */, + ); + path = AppCheck; + sourceTree = ""; + }; C796F29626CCDCEF0076C5F5 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -226,6 +238,7 @@ C7C6B573268C8C9A00546A57 /* Shared */ = { isa = PBXGroup; children = ( + 9A0FAF3426E7E37E0092BADD /* AppCheck */, C7C6B5A5268CED2600546A57 /* Models */, C7C6B5A4268CED2000546A57 /* Views */, C7C6B574268C8C9A00546A57 /* DatabaseExampleApp.swift */, @@ -569,6 +582,7 @@ C796F2B926D228490076C5F5 /* NewPostsView.swift in Sources */, C796F2BF26D228490076C5F5 /* Database+Extensions.swift in Sources */, C796F2B326D2283B0076C5F5 /* Comment.swift in Sources */, + 9A0FAF3826E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */, C796F2C026D228490076C5F5 /* DatabaseExampleApp.swift in Sources */, C796F2B426D2283E0076C5F5 /* UserViewModel.swift in Sources */, C796F2BD26D228490076C5F5 /* LoginView.swift in Sources */, @@ -591,6 +605,7 @@ C79D1AED26A8D9A300B6A169 /* PostsView.swift in Sources */, C77ABFAE26B8A7FF00BDE919 /* Database+Extensions.swift in Sources */, C7F60CFC268EE316002F68AB /* ContentView.swift in Sources */, + 9A0FAF3626E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */, C799B60E269E1CEF00A43C40 /* PostDetailView.swift in Sources */, C70B63FF2696B29400851A91 /* NewPostsView.swift in Sources */, C7F60CF2268E352F002F68AB /* SignUpView.swift in Sources */, @@ -613,6 +628,7 @@ C79D1AEE26A8D9A300B6A169 /* PostsView.swift in Sources */, C77ABFAF26B8A7FF00BDE919 /* Database+Extensions.swift in Sources */, C7F60CFD268EE316002F68AB /* ContentView.swift in Sources */, + 9A0FAF3726E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */, C799B60F269E1CEF00A43C40 /* PostDetailView.swift in Sources */, C70B64002696B29400851A91 /* NewPostsView.swift in Sources */, C7F60CF3268E352F002F68AB /* SignUpView.swift in Sources */, diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift new file mode 100644 index 000000000..9cb31ad99 --- /dev/null +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift @@ -0,0 +1,31 @@ +// +// Copyright (c) 2021 Google Inc. +// +// 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 +import Firebase + +class MyAppCheckProviderFactory: NSObject, AppCheckProviderFactory { + func createProvider(with app: FirebaseApp) -> AppCheckProvider? { + #if targetEnvironment(simulator) + // App Attest is not available on simulators. + // Use a debug provider. + return AppCheckDebugProvider(app: app) + #else + // Use App Attest provider on real devices. + return AppAttestProvider(app: app) + #endif + } +} diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift index f40e832e7..0fc4d7769 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift @@ -20,6 +20,9 @@ import Firebase @main struct DatabaseExampleApp: App { init() { + // Set an instance of `MyAppCheckProviderFactory` as an App Check provider factory before + // configuring Firebase. + AppCheck.setAppCheckProviderFactory(MyAppCheckProviderFactory()) FirebaseApp.configure() } From efa04d0ef5bb04fd1cd1f8ff03514d246704f060 Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Thu, 9 Sep 2021 17:21:32 -0400 Subject: [PATCH 03/11] App Attest capability --- .../DatabaseExample.entitlements | 8 ++++++++ .../DatabaseExample.xcodeproj/project.pbxproj | 20 +++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.entitlements diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.entitlements b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.entitlements new file mode 100644 index 000000000..eccdd1d2b --- /dev/null +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.developer.devicecheck.appattest-environment + production + + diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj index 85447d1c5..e7a34bae1 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj @@ -13,7 +13,9 @@ 9A0FAF3626E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; 9A0FAF3726E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; 9A0FAF3826E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; - B9029EF126A10B1500C92F12 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9029EF026A10B1500C92F12 /* GoogleService-Info.plist */; }; + 9A0FAF3E26EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; + 9A0FAF3F26EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; + 9A0FAF4026EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; C70B63FF2696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; C70B64002696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; C730A31F26B0998A00A29E81 /* PostsType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C730A31E26B0998A00A29E81 /* PostsType.swift */; }; @@ -29,9 +31,7 @@ C796F29A26CCDCF50076C5F5 /* FirebaseDatabase in Frameworks */ = {isa = PBXBuildFile; productRef = C796F29926CCDCF50076C5F5 /* FirebaseDatabase */; }; C796F29C26CCE3DA0076C5F5 /* ScreenDimensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C796F29B26CCE3DA0076C5F5 /* ScreenDimensions.swift */; }; C796F29D26CCE3DA0076C5F5 /* ScreenDimensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C796F29B26CCE3DA0076C5F5 /* ScreenDimensions.swift */; }; - C796F29E26CCE9DE0076C5F5 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9029EF026A10B1500C92F12 /* GoogleService-Info.plist */; }; C796F2AD26D2281A0076C5F5 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C796F2AC26D2281A0076C5F5 /* Preview Assets.xcassets */; }; - C796F2B226D228380076C5F5 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9029EF026A10B1500C92F12 /* GoogleService-Info.plist */; }; C796F2B326D2283B0076C5F5 /* Comment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7C6B5B2268DAC1800546A57 /* Comment.swift */; }; C796F2B426D2283E0076C5F5 /* UserViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7F60CF5268EBEDE002F68AB /* UserViewModel.swift */; }; C796F2B526D228410076C5F5 /* PostViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C79D1AC226A4114600B6A169 /* PostViewModel.swift */; }; @@ -103,7 +103,8 @@ /* Begin PBXFileReference section */ 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCheckProviderFactory.swift; sourceTree = ""; }; - B9029EF026A10B1500C92F12 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 9A0FAF4126EA914D0092BADD /* DatabaseExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DatabaseExample.entitlements; sourceTree = ""; }; C70B63FE2696B29400851A91 /* NewPostsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostsView.swift; sourceTree = ""; }; C730A31E26B0998A00A29E81 /* PostsType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostsType.swift; sourceTree = ""; }; C7690D8826DE0BD900F30AA6 /* UITests_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UITests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -225,7 +226,8 @@ C7C6B56E268C8C9A00546A57 = { isa = PBXGroup; children = ( - B9029EF026A10B1500C92F12 /* GoogleService-Info.plist */, + 9A0FAF4126EA914D0092BADD /* DatabaseExample.entitlements */, + 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */, C7C6B573268C8C9A00546A57 /* Shared */, C7C6B57D268C8C9C00546A57 /* iOS */, C7C6B584268C8C9C00546A57 /* macOS */, @@ -519,7 +521,7 @@ files = ( C796F2AD26D2281A0076C5F5 /* Preview Assets.xcassets in Resources */, C796F2C626D390010076C5F5 /* Assets.xcassets in Resources */, - C796F2B226D228380076C5F5 /* GoogleService-Info.plist in Resources */, + 9A0FAF4026EA90340092BADD /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -527,8 +529,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9A0FAF3E26EA90340092BADD /* GoogleService-Info.plist in Resources */, C7C6B58B268C8C9C00546A57 /* Assets.xcassets in Resources */, - B9029EF126A10B1500C92F12 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -536,8 +538,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9A0FAF3F26EA90340092BADD /* GoogleService-Info.plist in Resources */, C7C6B58C268C8C9C00546A57 /* Assets.xcassets in Resources */, - C796F29E26CCE9DE0076C5F5 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -980,6 +982,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = DatabaseExample.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iOS/Info.plist; From 581f9a68b0ce87b87bfe3fee9e085930c9a07d2e Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Thu, 9 Sep 2021 17:22:19 -0400 Subject: [PATCH 04/11] Rename App Check factory --- .../Shared/AppCheck/AppCheckProviderFactory.swift | 2 +- .../DatabaseExample/Shared/DatabaseExampleApp.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift index 9cb31ad99..9634d681d 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift @@ -17,7 +17,7 @@ import Foundation import Firebase -class MyAppCheckProviderFactory: NSObject, AppCheckProviderFactory { +class SimpleAppCheckProviderFactory: NSObject, AppCheckProviderFactory { func createProvider(with app: FirebaseApp) -> AppCheckProvider? { #if targetEnvironment(simulator) // App Attest is not available on simulators. diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift index 0fc4d7769..a48da2283 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift @@ -22,7 +22,7 @@ struct DatabaseExampleApp: App { init() { // Set an instance of `MyAppCheckProviderFactory` as an App Check provider factory before // configuring Firebase. - AppCheck.setAppCheckProviderFactory(MyAppCheckProviderFactory()) + AppCheck.setAppCheckProviderFactory(SimpleAppCheckProviderFactory()) FirebaseApp.configure() } From ce519e987aee773855ac883be277f7fddecdf776 Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Thu, 9 Sep 2021 17:23:53 -0400 Subject: [PATCH 05/11] Rename file --- .../DatabaseExample.xcodeproj/project.pbxproj | 16 ++++++++-------- ...swift => SimpleAppCheckProviderFactory.swift} | 0 2 files changed, 8 insertions(+), 8 deletions(-) rename database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/{AppCheckProviderFactory.swift => SimpleAppCheckProviderFactory.swift} (100%) diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj index e7a34bae1..0ece9c75f 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj @@ -10,9 +10,9 @@ 9A0FAF2F26E7CFD10092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF2E26E7CFD10092BADD /* FirebaseAppCheck */; }; 9A0FAF3126E7D1310092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF3026E7D1310092BADD /* FirebaseAppCheck */; }; 9A0FAF3326E7D1380092BADD /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF3226E7D1380092BADD /* FirebaseAppCheck */; }; - 9A0FAF3626E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; - 9A0FAF3726E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; - 9A0FAF3826E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */; }; + 9A0FAF3626E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift */; }; + 9A0FAF3726E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift */; }; + 9A0FAF3826E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3526E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift */; }; 9A0FAF3E26EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; 9A0FAF3F26EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; 9A0FAF4026EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; @@ -102,7 +102,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCheckProviderFactory.swift; sourceTree = ""; }; + 9A0FAF3526E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleAppCheckProviderFactory.swift; sourceTree = ""; }; 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 9A0FAF4126EA914D0092BADD /* DatabaseExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DatabaseExample.entitlements; sourceTree = ""; }; C70B63FE2696B29400851A91 /* NewPostsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostsView.swift; sourceTree = ""; }; @@ -194,7 +194,7 @@ 9A0FAF3426E7E37E0092BADD /* AppCheck */ = { isa = PBXGroup; children = ( - 9A0FAF3526E7E3A00092BADD /* AppCheckProviderFactory.swift */, + 9A0FAF3526E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift */, ); path = AppCheck; sourceTree = ""; @@ -584,7 +584,7 @@ C796F2B926D228490076C5F5 /* NewPostsView.swift in Sources */, C796F2BF26D228490076C5F5 /* Database+Extensions.swift in Sources */, C796F2B326D2283B0076C5F5 /* Comment.swift in Sources */, - 9A0FAF3826E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */, + 9A0FAF3826E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */, C796F2C026D228490076C5F5 /* DatabaseExampleApp.swift in Sources */, C796F2B426D2283E0076C5F5 /* UserViewModel.swift in Sources */, C796F2BD26D228490076C5F5 /* LoginView.swift in Sources */, @@ -607,7 +607,7 @@ C79D1AED26A8D9A300B6A169 /* PostsView.swift in Sources */, C77ABFAE26B8A7FF00BDE919 /* Database+Extensions.swift in Sources */, C7F60CFC268EE316002F68AB /* ContentView.swift in Sources */, - 9A0FAF3626E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */, + 9A0FAF3626E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */, C799B60E269E1CEF00A43C40 /* PostDetailView.swift in Sources */, C70B63FF2696B29400851A91 /* NewPostsView.swift in Sources */, C7F60CF2268E352F002F68AB /* SignUpView.swift in Sources */, @@ -630,7 +630,7 @@ C79D1AEE26A8D9A300B6A169 /* PostsView.swift in Sources */, C77ABFAF26B8A7FF00BDE919 /* Database+Extensions.swift in Sources */, C7F60CFD268EE316002F68AB /* ContentView.swift in Sources */, - 9A0FAF3726E7E3A00092BADD /* AppCheckProviderFactory.swift in Sources */, + 9A0FAF3726E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */, C799B60F269E1CEF00A43C40 /* PostDetailView.swift in Sources */, C70B64002696B29400851A91 /* NewPostsView.swift in Sources */, C7F60CF3268E352F002F68AB /* SignUpView.swift in Sources */, diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift similarity index 100% rename from database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/AppCheckProviderFactory.swift rename to database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift From fe72cd1d0f2c1b010db58c3f82a65f518a560fa3 Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Thu, 9 Sep 2021 18:16:58 -0400 Subject: [PATCH 06/11] Remote Config controlled App Check provider draft --- .../DatabaseExample.xcodeproj/project.pbxproj | 34 +++++++-- .../AppCheck/MyCustomAppCheckProvider.swift | 70 +++++++++++++++++++ .../Shared/DatabaseExampleApp.swift | 2 +- 3 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj index 0ece9c75f..dd3c1fb6e 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj @@ -16,6 +16,10 @@ 9A0FAF3E26EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; 9A0FAF3F26EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; 9A0FAF4026EA90340092BADD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */; }; + 9A0FAF4426EAB3AB0092BADD /* MyCustomAppCheckProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF4326EAB3AB0092BADD /* MyCustomAppCheckProvider.swift */; }; + 9A0FAF4526EAB3AB0092BADD /* MyCustomAppCheckProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF4326EAB3AB0092BADD /* MyCustomAppCheckProvider.swift */; }; + 9A0FAF4626EAB3AB0092BADD /* MyCustomAppCheckProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF4326EAB3AB0092BADD /* MyCustomAppCheckProvider.swift */; }; + 9A0FAF4A26EAB5E40092BADD /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF4926EAB5E40092BADD /* FirebaseRemoteConfig */; }; C70B63FF2696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; C70B64002696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; C730A31F26B0998A00A29E81 /* PostsType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C730A31E26B0998A00A29E81 /* PostsType.swift */; }; @@ -105,6 +109,7 @@ 9A0FAF3526E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleAppCheckProviderFactory.swift; sourceTree = ""; }; 9A0FAF3D26EA90340092BADD /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 9A0FAF4126EA914D0092BADD /* DatabaseExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DatabaseExample.entitlements; sourceTree = ""; }; + 9A0FAF4326EAB3AB0092BADD /* MyCustomAppCheckProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyCustomAppCheckProvider.swift; sourceTree = ""; }; C70B63FE2696B29400851A91 /* NewPostsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostsView.swift; sourceTree = ""; }; C730A31E26B0998A00A29E81 /* PostsType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostsType.swift; sourceTree = ""; }; C7690D8826DE0BD900F30AA6 /* UITests_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UITests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -175,6 +180,7 @@ C7C6B59B268C8D7800546A57 /* FirebaseDatabase in Frameworks */, C7C6B597268C8D7800546A57 /* FirebaseDatabaseSwift-Beta in Frameworks */, C7C6B599268C8D7800546A57 /* FirebaseAuth in Frameworks */, + 9A0FAF4A26EAB5E40092BADD /* FirebaseRemoteConfig in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -195,6 +201,7 @@ isa = PBXGroup; children = ( 9A0FAF3526E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift */, + 9A0FAF4326EAB3AB0092BADD /* MyCustomAppCheckProvider.swift */, ); path = AppCheck; sourceTree = ""; @@ -405,6 +412,7 @@ C7C6B598268C8D7800546A57 /* FirebaseAuth */, C7C6B59A268C8D7800546A57 /* FirebaseDatabase */, 9A0FAF2E26E7CFD10092BADD /* FirebaseAppCheck */, + 9A0FAF4926EAB5E40092BADD /* FirebaseRemoteConfig */, ); productName = "DatabaseExample (iOS)"; productReference = C7C6B57B268C8C9C00546A57 /* DatabaseExample.app */; @@ -587,6 +595,7 @@ 9A0FAF3826E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */, C796F2C026D228490076C5F5 /* DatabaseExampleApp.swift in Sources */, C796F2B426D2283E0076C5F5 /* UserViewModel.swift in Sources */, + 9A0FAF4626EAB3AB0092BADD /* MyCustomAppCheckProvider.swift in Sources */, C796F2BD26D228490076C5F5 /* LoginView.swift in Sources */, C796F2BB26D228490076C5F5 /* SignUpView.swift in Sources */, C796F2BA26D228490076C5F5 /* PostCell.swift in Sources */, @@ -610,6 +619,7 @@ 9A0FAF3626E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */, C799B60E269E1CEF00A43C40 /* PostDetailView.swift in Sources */, C70B63FF2696B29400851A91 /* NewPostsView.swift in Sources */, + 9A0FAF4426EAB3AB0092BADD /* MyCustomAppCheckProvider.swift in Sources */, C7F60CF2268E352F002F68AB /* SignUpView.swift in Sources */, C7C6B587268C8C9C00546A57 /* DatabaseExampleApp.swift in Sources */, C730A31F26B0998A00A29E81 /* PostsType.swift in Sources */, @@ -633,6 +643,7 @@ 9A0FAF3726E7E3A00092BADD /* SimpleAppCheckProviderFactory.swift in Sources */, C799B60F269E1CEF00A43C40 /* PostDetailView.swift in Sources */, C70B64002696B29400851A91 /* NewPostsView.swift in Sources */, + 9A0FAF4526EAB3AB0092BADD /* MyCustomAppCheckProvider.swift in Sources */, C7F60CF3268E352F002F68AB /* SignUpView.swift in Sources */, C7C6B588268C8C9C00546A57 /* DatabaseExampleApp.swift in Sources */, C730A32026B0998A00A29E81 /* PostsType.swift in Sources */, @@ -985,6 +996,7 @@ CODE_SIGN_ENTITLEMENTS = DatabaseExample.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 374XEWX2QT; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iOS/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -992,8 +1004,9 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExample; + PRODUCT_BUNDLE_IDENTIFIER = com.google.mmaksym.DeviceTokenGenerator; PRODUCT_NAME = DatabaseExample; + PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1005,7 +1018,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = DatabaseExample.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 374XEWX2QT; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iOS/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -1013,8 +1029,9 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExample; + PRODUCT_BUNDLE_IDENTIFIER = com.google.mmaksym.DeviceTokenGenerator; PRODUCT_NAME = DatabaseExample; + PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1028,8 +1045,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 374XEWX2QT; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = macOS/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -1037,7 +1056,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 11.0; - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExample; + PRODUCT_BUNDLE_IDENTIFIER = com.google.mmaksym.DeviceTokenGenerator; PRODUCT_NAME = DatabaseExample; SDKROOT = macosx; SWIFT_VERSION = 5.0; @@ -1050,8 +1069,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 374XEWX2QT; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = macOS/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -1059,7 +1080,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 11.0; - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExample; + PRODUCT_BUNDLE_IDENTIFIER = com.google.mmaksym.DeviceTokenGenerator; PRODUCT_NAME = DatabaseExample; SDKROOT = macosx; SWIFT_VERSION = 5.0; @@ -1161,6 +1182,11 @@ package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseAppCheck; }; + 9A0FAF4926EAB5E40092BADD /* FirebaseRemoteConfig */ = { + isa = XCSwiftPackageProductDependency; + package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseRemoteConfig; + }; C796F29726CCDCEF0076C5F5 /* FirebaseAuth */ = { isa = XCSwiftPackageProductDependency; package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift new file mode 100644 index 000000000..1fd8075a9 --- /dev/null +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift @@ -0,0 +1,70 @@ +// +// Copyright (c) 2021 Google Inc. +// +// 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 +import Firebase + + +class MyCustomAppCheckProvider: NSObject, AppCheckProvider { + enum ProviderError: Error { + case appAttestIsDisabled + case appAttestIsUnavailable + } + + let appAttestRemoteConfigFlagName = "app-attest-enabled" + + let firebaseApp: FirebaseApp + + init(firebaseApp: FirebaseApp) { + self.firebaseApp = firebaseApp + } + + private var _appAttestProvider: AppAttestProvider? + private var appAttestProvider: AppAttestProvider? { + if let appAttestProvider = _appAttestProvider { + return appAttestProvider + } else { + _appAttestProvider = AppAttestProvider(app: self.firebaseApp) + return _appAttestProvider + } + } + + func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) { + // Fetch App Attest flag from remote config. + let remoteConfig = RemoteConfig.remoteConfig(app:firebaseApp) + + let appAttestEnabled = remoteConfig[appAttestRemoteConfigFlagName].boolValue + + guard appAttestEnabled else { + handler(nil, ProviderError.appAttestIsDisabled) + return + } + + // If App Attest is enabled for the app instance then forward the Firebase App Check token request to App Attest provider. + guard let appAttestProvider = self.appAttestProvider else { + handler(nil, ProviderError.appAttestIsUnavailable) + return + } + + appAttestProvider.getToken(completion: handler) + } + + class Factory: NSObject, AppCheckProviderFactory { + func createProvider(with app: FirebaseApp) -> AppCheckProvider? { + return MyCustomAppCheckProvider(firebaseApp: app) + } + } +} diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift index a48da2283..fe1bd7ffb 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/DatabaseExampleApp.swift @@ -22,7 +22,7 @@ struct DatabaseExampleApp: App { init() { // Set an instance of `MyAppCheckProviderFactory` as an App Check provider factory before // configuring Firebase. - AppCheck.setAppCheckProviderFactory(SimpleAppCheckProviderFactory()) + AppCheck.setAppCheckProviderFactory(MyCustomAppCheckProvider.Factory()) FirebaseApp.configure() } From d231bbf003c916e75cb7df367defa5f17aff54f5 Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Fri, 10 Sep 2021 11:03:03 -0400 Subject: [PATCH 07/11] Custom App Check provider with Remote Config and A/B testing integration for conditional App Attest rollout. --- .../DatabaseExample.xcodeproj/project.pbxproj | 8 ++ .../DatabaseExample/GoogleService-Info.plist | 40 ++++----- .../AppCheck/MyCustomAppCheckProvider.swift | 86 +++++++++++++++---- 3 files changed, 93 insertions(+), 41 deletions(-) diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj index dd3c1fb6e..14bbfcf13 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/DatabaseExample.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ 9A0FAF4526EAB3AB0092BADD /* MyCustomAppCheckProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF4326EAB3AB0092BADD /* MyCustomAppCheckProvider.swift */; }; 9A0FAF4626EAB3AB0092BADD /* MyCustomAppCheckProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FAF4326EAB3AB0092BADD /* MyCustomAppCheckProvider.swift */; }; 9A0FAF4A26EAB5E40092BADD /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF4926EAB5E40092BADD /* FirebaseRemoteConfig */; }; + 9A0FAF4C26EB95E20092BADD /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 9A0FAF4B26EB95E20092BADD /* FirebaseAnalytics */; }; C70B63FF2696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; C70B64002696B29400851A91 /* NewPostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70B63FE2696B29400851A91 /* NewPostsView.swift */; }; C730A31F26B0998A00A29E81 /* PostsType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C730A31E26B0998A00A29E81 /* PostsType.swift */; }; @@ -178,6 +179,7 @@ files = ( 9A0FAF2F26E7CFD10092BADD /* FirebaseAppCheck in Frameworks */, C7C6B59B268C8D7800546A57 /* FirebaseDatabase in Frameworks */, + 9A0FAF4C26EB95E20092BADD /* FirebaseAnalytics in Frameworks */, C7C6B597268C8D7800546A57 /* FirebaseDatabaseSwift-Beta in Frameworks */, C7C6B599268C8D7800546A57 /* FirebaseAuth in Frameworks */, 9A0FAF4A26EAB5E40092BADD /* FirebaseRemoteConfig in Frameworks */, @@ -413,6 +415,7 @@ C7C6B59A268C8D7800546A57 /* FirebaseDatabase */, 9A0FAF2E26E7CFD10092BADD /* FirebaseAppCheck */, 9A0FAF4926EAB5E40092BADD /* FirebaseRemoteConfig */, + 9A0FAF4B26EB95E20092BADD /* FirebaseAnalytics */, ); productName = "DatabaseExample (iOS)"; productReference = C7C6B57B268C8C9C00546A57 /* DatabaseExample.app */; @@ -1187,6 +1190,11 @@ package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseRemoteConfig; }; + 9A0FAF4B26EB95E20092BADD /* FirebaseAnalytics */ = { + isa = XCSwiftPackageProductDependency; + package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAnalytics; + }; C796F29726CCDCEF0076C5F5 /* FirebaseAuth */ = { isa = XCSwiftPackageProductDependency; package = C7C6B595268C8D7800546A57 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/GoogleService-Info.plist b/database/DatabaseExampleSwiftUI/DatabaseExample/GoogleService-Info.plist index 9fe4b489f..5625afcf3 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/GoogleService-Info.plist +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/GoogleService-Info.plist @@ -2,39 +2,31 @@ - AD_UNIT_ID_FOR_BANNER_TEST - ca-app-pub-3940256099942544/2934735716 - AD_UNIT_ID_FOR_INTERSTITIAL_TEST - ca-app-pub-3940256099942544/4411468910 API_KEY - AIzaSyAzlj4APqi5S58nFtE52Da0fYBOHA2MhaY - BUNDLE_ID - com.google.firebase.quickstart.DatabaseExample - CLIENT_ID - 123456789000-hjugbg6ud799v4c49dim8ce2usclthar.apps.googleusercontent.com - DATABASE_URL - https://mockproject-1234.firebaseio.com + AIzaSyDK5Za83R4xZP8l2ff-EvXiA9xCyf2i29o GCM_SENDER_ID - 123456789000 - GOOGLE_APP_ID - 1:123456789000:ios:f1bf012572b04063 + 206117040282 + PLIST_VERSION + 1 + BUNDLE_ID + com.google.mmaksym.DeviceTokenGenerator + PROJECT_ID + rtdb-with-app-check-codelab + STORAGE_BUCKET + rtdb-with-app-check-codelab.appspot.com IS_ADS_ENABLED - + IS_ANALYTICS_ENABLED - + IS_APPINVITE_ENABLED IS_GCM_ENABLED IS_SIGNIN_ENABLED - PLIST_VERSION - 1 - PROJECT_ID - mockproject-1234 - REVERSED_CLIENT_ID - com.googleusercontent.apps.123456789000-hjugbg6ud799v4c49dim8ce2usclthar - STORAGE_BUCKET - mockproject-1234.appspot.com + GOOGLE_APP_ID + 1:206117040282:ios:17ebb5812d240da753af23 + DATABASE_URL + https://rtdb-with-app-check-codelab-default-rtdb.firebaseio.com diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift index 1fd8075a9..c78ac5187 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift @@ -15,21 +15,25 @@ // import Foundation -import Firebase +import DeviceCheck +import Firebase class MyCustomAppCheckProvider: NSObject, AppCheckProvider { - enum ProviderError: Error { - case appAttestIsDisabled - case appAttestIsUnavailable - } - - let appAttestRemoteConfigFlagName = "app-attest-enabled" - let firebaseApp: FirebaseApp init(firebaseApp: FirebaseApp) { self.firebaseApp = firebaseApp + + super.init() + + // Log Analytics event if App Attest is available. + logAppAttestAvailability() + + #if DEBUG + // Print FIS Auth token for + self.printFISToken() + #endif } private var _appAttestProvider: AppAttestProvider? @@ -45,26 +49,74 @@ class MyCustomAppCheckProvider: NSObject, AppCheckProvider { func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) { // Fetch App Attest flag from remote config. let remoteConfig = RemoteConfig.remoteConfig(app:firebaseApp) + remoteConfig.fetchAndActivate { remoteConfigStatus, error in + // Get App Attest flag value. + let appAttestEnabled = remoteConfig[Constants.appAttestRemoteConfigFlagName].boolValue + + guard appAttestEnabled else { + // Skip attestation if App Attest is disabled. Another attestation method like DeviceCheck may be used instead of just skipping. + handler(nil, ProviderError.appAttestIsDisabled) + return + } + + // Try to obtain App Attest provider instance and fail if cannot. + guard let appAttestProvider = self.appAttestProvider else { + handler(nil, ProviderError.appAttestIsUnavailable) + return + } - let appAttestEnabled = remoteConfig[appAttestRemoteConfigFlagName].boolValue + // If App Attest is enabled for the app instance then forward the Firebase App Check token request to App Attest provider. + appAttestProvider.getToken { token, error in + // Log an analytics event to track attestation success rate and make a decision if App Attest rollout should proceed. + let appAttestEvent = (token != nil && error == nil) ? Constants.appAttestAvailableSuccessEventName : Constants.appAttestAvailableFailureEventName + Analytics.logEvent(appAttestEvent, parameters: nil) - guard appAttestEnabled else { - handler(nil, ProviderError.appAttestIsDisabled) - return + // Pass the result to the handler. + handler(token, error) + } } + } - // If App Attest is enabled for the app instance then forward the Firebase App Check token request to App Attest provider. - guard let appAttestProvider = self.appAttestProvider else { - handler(nil, ProviderError.appAttestIsUnavailable) - return + /// Logs an Analytics event if App Attest is available. It will be used as a trigger for the App Attest rollout A/B testing experiment. + private func logAppAttestAvailability() { + if DCAppAttestService.shared.isSupported { + Analytics.logEvent(Constants.appAttestAvailableEventName, parameters: nil) } + } - appAttestProvider.getToken(completion: handler) + /// Retrieves and prints a Firebase Installations Service (FIS) auth token. + /// The token can be used to assign a particular A/B testing experiment variant to a test device. + private func printFISToken() { + Installations.installations(app: firebaseApp).authToken { tokenResult, error in + print("FIS auth token: \(String(describing: tokenResult?.authToken))") + } } + // A factory class to connect the custom provider to Firebase App Check. class Factory: NSObject, AppCheckProviderFactory { func createProvider(with app: FirebaseApp) -> AppCheckProvider? { return MyCustomAppCheckProvider(firebaseApp: app) } } } + +extension MyCustomAppCheckProvider { + /// The provider errors enum. + enum ProviderError: Error { + case appAttestIsDisabled + case appAttestIsUnavailable + } + + /// Constants. + enum Constants { + /// Remote Config flag name for enabling/disabling App Attest. + static let appAttestRemoteConfigFlagName = "AppAttestEnabled" + + /// Analytics event name to log if App Attest is available on the device. + static let appAttestAvailableEventName = "AppAttestAvailable" + /// Analytics event name to log when App Attest attestation succeeds. + static let appAttestAvailableSuccessEventName = "AppAttestSuccess" + /// Analytics event name to log when App Attest attestation fails. + static let appAttestAvailableFailureEventName = "AppAttestFailure" + } +} From c71c7c77efbfef6174a8742d00db91e07a208247 Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Wed, 15 Sep 2021 21:39:46 -0400 Subject: [PATCH 08/11] Use lazy property --- .../Shared/AppCheck/MyCustomAppCheckProvider.swift | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift index c78ac5187..8d167efd8 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift @@ -36,15 +36,9 @@ class MyCustomAppCheckProvider: NSObject, AppCheckProvider { #endif } - private var _appAttestProvider: AppAttestProvider? - private var appAttestProvider: AppAttestProvider? { - if let appAttestProvider = _appAttestProvider { - return appAttestProvider - } else { - _appAttestProvider = AppAttestProvider(app: self.firebaseApp) - return _appAttestProvider - } - } + private lazy var appAttestProvider: AppAttestProvider? = { + return AppAttestProvider(app: self.firebaseApp) + }() func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) { // Fetch App Attest flag from remote config. @@ -65,6 +59,8 @@ class MyCustomAppCheckProvider: NSObject, AppCheckProvider { return } + appAttestProvider.getToken(completion: handler) + // If App Attest is enabled for the app instance then forward the Firebase App Check token request to App Attest provider. appAttestProvider.getToken { token, error in // Log an analytics event to track attestation success rate and make a decision if App Attest rollout should proceed. From a6d14f41e43b54d1b194d706716e990e3ee21f93 Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Wed, 15 Sep 2021 21:41:04 -0400 Subject: [PATCH 09/11] Factory: print debug provider, DeviceCheck fallback --- .../SimpleAppCheckProviderFactory.swift | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift index 9634d681d..1c50e98c5 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift @@ -19,13 +19,22 @@ import Firebase class SimpleAppCheckProviderFactory: NSObject, AppCheckProviderFactory { func createProvider(with app: FirebaseApp) -> AppCheckProvider? { - #if targetEnvironment(simulator) + #if targetEnvironment(simulator) // App Attest is not available on simulators. // Use a debug provider. - return AppCheckDebugProvider(app: app) - #else - // Use App Attest provider on real devices. - return AppAttestProvider(app: app) - #endif + let provider = AppCheckDebugProvider(app: app) + + // Print only locally generated token to avoid a valid token leak on CI. + print("Firebase App Check debug token: \(provider?.localDebugToken() ?? "" )") + + return provider + #else + if #available(iOS 14.0, *) { + // Use App Attest provider on real devices. + return AppAttestProvider(app: app) + } else { + return DeviceCheckProvider(app: app) + } + #endif } } From 1f2b5a585a54730ea3abcbc44d9c1d9c47201e0b Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Thu, 16 Sep 2021 10:33:17 -0400 Subject: [PATCH 10/11] Remove .plist --- .../DatabaseExample/GoogleService-Info.plist | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 database/DatabaseExampleSwiftUI/DatabaseExample/GoogleService-Info.plist diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/GoogleService-Info.plist b/database/DatabaseExampleSwiftUI/DatabaseExample/GoogleService-Info.plist deleted file mode 100644 index 5625afcf3..000000000 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/GoogleService-Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - API_KEY - AIzaSyDK5Za83R4xZP8l2ff-EvXiA9xCyf2i29o - GCM_SENDER_ID - 206117040282 - PLIST_VERSION - 1 - BUNDLE_ID - com.google.mmaksym.DeviceTokenGenerator - PROJECT_ID - rtdb-with-app-check-codelab - STORAGE_BUCKET - rtdb-with-app-check-codelab.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:206117040282:ios:17ebb5812d240da753af23 - DATABASE_URL - https://rtdb-with-app-check-codelab-default-rtdb.firebaseio.com - - From e15ed5fb012473501ec8afbe259ea496b4cadb7e Mon Sep 17 00:00:00 2001 From: Maksym Malyhin Date: Mon, 20 Sep 2021 13:34:55 -0400 Subject: [PATCH 11/11] Comments and formatting --- .../AppCheck/MyCustomAppCheckProvider.swift | 20 ++++++++++++++----- .../SimpleAppCheckProviderFactory.swift | 10 +++++----- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift index 8d167efd8..9810d82ed 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/MyCustomAppCheckProvider.swift @@ -19,6 +19,15 @@ import DeviceCheck import Firebase +/// The App Check provider that uses Firebase Remote Config to either forward +/// Firebase App Check token request to the standard AppAttestProvider fail +/// to skip attestation. The attestation provider also logs Analytics events to +/// track if App Attest API is available on a device and if attestation +/// succeeded or failed. The main motivation to use the custom App Check +/// provider is to gradually enable App Attest attestation to avoid throttling +/// form Apple backend. Another reason is tracking additional metrics with +/// Firebase Analytics. +/// NOTE: This is an example and may require additional optimizations to ensure the best performance in a production app, e.g. you may want to avoid fetching and activating Remote Config as a part of attestation and prefer to do it separately to avoid additional latency of the attestation process. class MyCustomAppCheckProvider: NSObject, AppCheckProvider { let firebaseApp: FirebaseApp @@ -31,18 +40,18 @@ class MyCustomAppCheckProvider: NSObject, AppCheckProvider { logAppAttestAvailability() #if DEBUG - // Print FIS Auth token for - self.printFISToken() + // Print FIS Auth token for + printFISToken() #endif } private lazy var appAttestProvider: AppAttestProvider? = { - return AppAttestProvider(app: self.firebaseApp) + AppAttestProvider(app: self.firebaseApp) }() func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) { // Fetch App Attest flag from remote config. - let remoteConfig = RemoteConfig.remoteConfig(app:firebaseApp) + let remoteConfig = RemoteConfig.remoteConfig(app: firebaseApp) remoteConfig.fetchAndActivate { remoteConfigStatus, error in // Get App Attest flag value. let appAttestEnabled = remoteConfig[Constants.appAttestRemoteConfigFlagName].boolValue @@ -64,7 +73,8 @@ class MyCustomAppCheckProvider: NSObject, AppCheckProvider { // If App Attest is enabled for the app instance then forward the Firebase App Check token request to App Attest provider. appAttestProvider.getToken { token, error in // Log an analytics event to track attestation success rate and make a decision if App Attest rollout should proceed. - let appAttestEvent = (token != nil && error == nil) ? Constants.appAttestAvailableSuccessEventName : Constants.appAttestAvailableFailureEventName + let appAttestEvent = (token != nil && error == nil) ? Constants + .appAttestAvailableSuccessEventName : Constants.appAttestAvailableFailureEventName Analytics.logEvent(appAttestEvent, parameters: nil) // Pass the result to the handler. diff --git a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift index 1c50e98c5..4bf35e7a0 100644 --- a/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift +++ b/database/DatabaseExampleSwiftUI/DatabaseExample/Shared/AppCheck/SimpleAppCheckProviderFactory.swift @@ -19,22 +19,22 @@ import Firebase class SimpleAppCheckProviderFactory: NSObject, AppCheckProviderFactory { func createProvider(with app: FirebaseApp) -> AppCheckProvider? { - #if targetEnvironment(simulator) + #if targetEnvironment(simulator) // App Attest is not available on simulators. // Use a debug provider. let provider = AppCheckDebugProvider(app: app) // Print only locally generated token to avoid a valid token leak on CI. - print("Firebase App Check debug token: \(provider?.localDebugToken() ?? "" )") + print("Firebase App Check debug token: \(provider?.localDebugToken() ?? "")") return provider - #else + #else if #available(iOS 14.0, *) { // Use App Attest provider on real devices. - return AppAttestProvider(app: app) + return MyCustomAppCheckProvider(app: app) } else { return DeviceCheckProvider(app: app) } - #endif + #endif } }