From c3218da730a78b1922e8d754b97e703a0fa58dfd Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Mon, 16 Mar 2026 10:00:16 -0700 Subject: [PATCH 01/18] init --- mobile/asa-go/Notifications.md | 151 +++++++++++++ mobile/asa-go/README.md | 18 +- mobile/asa-go/android/app/build.gradle | 48 +++-- mobile/asa-go/android/app/src/dev/.gitkeep | 1 + .../android/app/src/main/AndroidManifest.xml | 2 +- .../java/ca/bc/gov/asago/MainActivity.java | 3 +- mobile/asa-go/android/app/src/prod/.gitkeep | 0 .../ca/bc/gov/asago/MainActivityTest.java | 65 +++--- mobile/asa-go/capacitor.config.ts | 14 +- mobile/asa-go/ios/App/ASA Go dev-Info.plist | 72 +++++++ .../ios/App/App.xcodeproj/project.pbxproj | 199 ++++++++++++++++-- .../xcshareddata/swiftpm/Package.resolved | 123 ----------- mobile/asa-go/ios/App/Podfile | 6 + mobile/asa-go/ios/App/Podfile.lock | 32 +-- mobile/asa-go/package.json | 7 +- mobile/asa-go/tsconfig.node.json | 3 +- mobile/asa-go/yarn.lock | 7 + 17 files changed, 536 insertions(+), 215 deletions(-) create mode 100644 mobile/asa-go/Notifications.md create mode 100644 mobile/asa-go/android/app/src/dev/.gitkeep create mode 100644 mobile/asa-go/android/app/src/prod/.gitkeep create mode 100644 mobile/asa-go/ios/App/ASA Go dev-Info.plist delete mode 100644 mobile/asa-go/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/mobile/asa-go/Notifications.md b/mobile/asa-go/Notifications.md new file mode 100644 index 0000000000..8983dccb4b --- /dev/null +++ b/mobile/asa-go/Notifications.md @@ -0,0 +1,151 @@ +# Notifications + +Short reference for the ASA Go mobile notification setup. + +## iOS app IDs + +We have two iOS app variants: + +- Prod bundle ID: `ca.bc.gov.asago` +- Dev bundle ID: `ca.bc.gov.asago.dev` + +These bundle IDs must match the Firebase iOS app registration exactly. + +## Android app IDs + +We also have two Android app variants: + +- Prod application ID: `ca.bc.gov.asago` +- Dev application ID: `ca.bc.gov.asago.dev` + +These application IDs must match the Firebase Android app registration exactly. + +## Firebase dev vs prod + +We use different Firebase app configs for prod and dev on both platforms. + +- Prod Firebase plist: `ios/App/App/Firebase/Prod/GoogleService-Info.plist` +- Dev Firebase plist: `ios/App/App/Firebase/Dev/GoogleService-Info.plist` +- Prod Android config: `android/app/src/prod/google-services.json` +- Dev Android config: `android/app/src/dev/google-services.json` + +Current mapping: + +- Prod plist `BUNDLE_ID`: `ca.bc.gov.asago` +- Dev plist `BUNDLE_ID`: `ca.bc.gov.asago.dev` + +If the wrong plist is used, Firebase Messaging will not be configured for the installed app correctly. + +The same rule applies on Android: if the wrong `google-services.json` is used, Firebase Messaging will not be configured for the installed app correctly. + +## GoogleService-Info.plist + +`GoogleService-Info.plist` is the iOS Firebase app config file. + +It tells the app which Firebase project/app to talk to, including: + +- Firebase project ID +- iOS app ID +- sender ID +- API key +- expected iOS bundle ID + +It is required locally in the iOS project. + +## google-services.json + +`google-services.json` is the Android Firebase app config file. + +It tells the Android app which Firebase project/app to talk to, including: + +- Firebase project ID +- Android app ID +- sender ID +- API key +- expected Android application ID + +It is required locally in the Android project. + +## APNs auth key + +The APNs auth key is the Apple push key used by Firebase to send iOS notifications through APNs. + +Important points: + +- It does not go in this repo. +- It does not go in Xcode project files. +- It is uploaded in Firebase Console. +- It can be used for both development and production APNs delivery. + +Because we have separate Firebase setups for dev and prod, make sure the Firebase project used by each app has APNs configured. + +## What lives where + +In the app repo: + +- iOS bundle IDs +- Android application IDs / flavors +- Xcode targets/schemes +- `GoogleService-Info.plist` +- `google-services.json` +- Capacitor config + +In Firebase Console: + +- APNs auth key upload +- Firebase app registration for each bundle ID +- Cloud Messaging setup + +## Auth callback scheme + +The Android dev and prod flavors currently share the same AppAuth redirect scheme: + +- `ca.bc.gov.asago` + +That matches the older auth setup. The app IDs are still different, but the auth callback scheme is shared. + +This is workable, but there is one tradeoff: if both Android app variants are installed on the same device, a custom-scheme auth callback can be ambiguous because both apps can claim the same scheme. + +## Why we use separate app IDs + +This repo uses separate app IDs for dev and prod instead of trying to inject only Firebase config into one app identity. + +Why this is useful: + +- dev and prod can both be installed on the same iPhone +- dev and prod can both be installed on the same Android device +- dev push notifications stay separate from prod +- dev testing is less likely to affect the prod app +- the Firebase app registration is clearer because each app variant has its own app ID + +An alternative is to keep one app ID and inject different config at build time. That can work, but it means dev and prod are still the same app identity, so they cannot be installed side by side. + +## Running dev vs prod + +`capacitor.config.ts` switches between dev and prod using `APP_ENV`. + +Examples: + +```bash +APP_ENV=dev yarn cap:sync:ios:dev +APP_ENV=prod yarn cap:sync:ios:prod +``` + +For live reload: + +```bash +APP_ENV=dev ionic capacitor run ios -l --external +APP_ENV=prod ionic capacitor run ios -l --external +APP_ENV=dev ionic capacitor run android -l --external +APP_ENV=prod ionic capacitor run android -l --external +``` + +## Quick checks + +If notifications are not working, check these first: + +1. The installed app's iOS bundle ID or Android application ID matches the Firebase app config. +2. The correct `GoogleService-Info.plist` or `google-services.json` is included for the target/flavor. +3. APNs auth key is uploaded in the correct Firebase project. +4. The iOS app is running on a real iPhone, not the iOS simulator. +5. Push permissions were granted on the device. diff --git a/mobile/asa-go/README.md b/mobile/asa-go/README.md index 244a8503e1..d132ad94d0 100644 --- a/mobile/asa-go/README.md +++ b/mobile/asa-go/README.md @@ -2,6 +2,8 @@ Capacitor app using react/vite. +For iOS/Firebase push notification setup details, see [Notifications.md](Notifications.md). + ## Building The keycloak plugin must be built before installing asa-go dependencies, as asa-go resolves it as a local path dependency. @@ -18,6 +20,11 @@ yarn install yarn build ``` +APP_ENV=dev ionic capacitor run ios -l --external +APP_ENV=prod ionic capacitor run ios -l --external +APP_ENV=dev ionic capacitor run android -l --external +APP_ENV=prod ionic capacitor run android -l --external + ## Setup live reload 1. Install ionic CLI and native run for live reload with: `npm install -g @ionic/cli native-run` @@ -26,8 +33,8 @@ yarn build 1. Make sure xcode is installed with `xcode-select --install` 2. Go to `mobile/asa-go` -3. Run `yarn cap sync ios` to synchronize app with iOS platform (handles `pod install`) -4. Build and run with live reload: `ionic cap run ios -l --external` +3. Run `APP_ENV=dev yarn cap:sync:ios:dev` or `APP_ENV=prod yarn cap:sync:ios:prod` +4. Build and run with live reload: `APP_ENV=dev ionic capacitor run ios -l --external` or `APP_ENV=prod ionic capacitor run ios -l --external` ### Building/Running Android @@ -36,14 +43,15 @@ yarn build - With Jetbrains Toolbox it should be `/Users//Library/Android/sdk/` - Set `$ANDROID_HOME` to the path of the Android SDK 3. Go to `mobile/asa-go` -4. Run `yarn cap sync android` to synchronize app with Android platform -5. Build and run with live reload: `ionic cap run android -l --external` +4. Run `APP_ENV=dev yarn cap:sync:android:dev` or `APP_ENV=prod yarn cap:sync:android:prod` +5. Build and run with live reload: `APP_ENV=dev ionic capacitor run android -l --external` or `APP_ENV=prod ionic capacitor run android -l --external` To build a debug APK directly: ```bash cd mobile/asa-go/android -./gradlew assembleDebug +./gradlew assembleDevDebug +./gradlew assembleProdDebug ``` #### Running on a physical Android device against your local API diff --git a/mobile/asa-go/android/app/build.gradle b/mobile/asa-go/android/app/build.gradle index 66e92873ab..f54fda8595 100644 --- a/mobile/asa-go/android/app/build.gradle +++ b/mobile/asa-go/android/app/build.gradle @@ -5,8 +5,14 @@ apply plugin: 'com.google.gms.google-services' android { namespace "ca.bc.gov.asago" compileSdk rootProject.ext.compileSdkVersion + + buildFeatures { + buildConfig true + } + + flavorDimensions "env" + defaultConfig { - applicationId "ca.bc.gov.asago" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode System.getenv("VERSION_CODE") ? System.getenv("VERSION_CODE").toInteger() : 7 @@ -21,6 +27,23 @@ android { appAuthRedirectScheme: "ca.bc.gov.asago", appAuthManagementActivity: "ca.bc.gov.asago.MainActivity" ] + buildConfigField "String", "APP_AUTH_REDIRECT_SCHEME", "\"ca.bc.gov.asago\"" + } + productFlavors { + dev { + dimension "env" + applicationId "ca.bc.gov.asago.dev" + resValue "string", "app_name", "ASA Go Dev" + resValue "string", "title_activity_main", "ASA Go Dev" + resValue "string", "custom_url_scheme", "ca.bc.gov.asago" + } + prod { + dimension "env" + applicationId "ca.bc.gov.asago" + resValue "string", "app_name", "ASA Go" + resValue "string", "title_activity_main", "ASA Go" + resValue "string", "custom_url_scheme", "ca.bc.gov.asago" + } } signingConfigs { release { @@ -76,23 +99,20 @@ tasks.withType(Test) { jacoco.excludes = ['jdk.internal.*'] } -task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) { +task jacocoTestReport(type: JacocoReport, dependsOn: ['testDevDebugUnitTest', 'testProdDebugUnitTest']) { reports { xml.required = true html.required = false } def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*'] - def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug/compileDebugJavaWithJavac/classes", excludes: fileFilter) + def debugTrees = files( + fileTree(dir: "${buildDir}/intermediates/javac/devDebug/compileDevDebugJavaWithJavac/classes", excludes: fileFilter), + fileTree(dir: "${buildDir}/intermediates/javac/prodDebug/compileProdDebugJavaWithJavac/classes", excludes: fileFilter) + ) sourceDirectories.setFrom(files(["${project.projectDir}/src/main/java"])) - classDirectories.setFrom(files([debugTree])) - executionData.setFrom(fileTree(dir: "$buildDir", includes: ["jacoco/testDebugUnitTest.exec"])) -} - -try { - def servicesJSON = file('google-services.json') - if (servicesJSON.text) { - apply plugin: 'com.google.gms.google-services' - } -} catch(Exception e) { - logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") + classDirectories.setFrom(debugTrees) + executionData.setFrom(fileTree(dir: "$buildDir", includes: [ + "jacoco/testDevDebugUnitTest.exec", + "jacoco/testProdDebugUnitTest.exec" + ])) } diff --git a/mobile/asa-go/android/app/src/dev/.gitkeep b/mobile/asa-go/android/app/src/dev/.gitkeep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/mobile/asa-go/android/app/src/dev/.gitkeep @@ -0,0 +1 @@ + diff --git a/mobile/asa-go/android/app/src/main/AndroidManifest.xml b/mobile/asa-go/android/app/src/main/AndroidManifest.xml index cf1969f6a9..856abc6603 100644 --- a/mobile/asa-go/android/app/src/main/AndroidManifest.xml +++ b/mobile/asa-go/android/app/src/main/AndroidManifest.xml @@ -33,7 +33,7 @@ - + mockedStatic = mockStatic(KeycloakPlugin.class)) { mockedStatic.when(KeycloakPlugin::getInstance).thenReturn(mockPlugin); - Uri testUri = Uri.parse("ca.bc.gov.asago://callback?code=testcode"); + Uri testUri = Uri.parse(authUri("callback?code=testcode")); KeycloakPlugin plugin = KeycloakPlugin.getInstance(); - if (plugin != null && "ca.bc.gov.asago".equals(testUri.getScheme())) { + if (plugin != null && AUTH_REDIRECT_SCHEME.equals(testUri.getScheme())) { plugin.handleAuthCallback(testUri); } @@ -109,7 +114,7 @@ public void testHandleAuthCallback_notCalledForWrongScheme() { Uri testUri = Uri.parse("https://example.com/callback"); KeycloakPlugin plugin = KeycloakPlugin.getInstance(); - if (plugin != null && "ca.bc.gov.asago".equals(testUri.getScheme())) { + if (plugin != null && AUTH_REDIRECT_SCHEME.equals(testUri.getScheme())) { plugin.handleAuthCallback(testUri); } @@ -122,11 +127,11 @@ public void testHandleAuthCallback_notCalledWhenPluginIsNull() { try (MockedStatic mockedStatic = mockStatic(KeycloakPlugin.class)) { mockedStatic.when(KeycloakPlugin::getInstance).thenReturn(null); - Uri testUri = Uri.parse("ca.bc.gov.asago://callback?code=test"); + Uri testUri = Uri.parse(authUri("callback?code=test")); KeycloakPlugin plugin = KeycloakPlugin.getInstance(); // This should not throw NullPointerException - if (plugin != null && "ca.bc.gov.asago".equals(testUri.getScheme())) { + if (plugin != null && AUTH_REDIRECT_SCHEME.equals(testUri.getScheme())) { plugin.handleAuthCallback(testUri); } @@ -144,7 +149,7 @@ public void testIntentData_canBeNull() { @Test public void testIntentData_canBeExtracted() { - Uri testUri = Uri.parse("ca.bc.gov.asago://callback"); + Uri testUri = Uri.parse(authUri("callback")); Intent intent = new Intent(Intent.ACTION_VIEW, testUri); Uri data = intent.getData(); @@ -155,16 +160,16 @@ public void testIntentData_canBeExtracted() { @Test public void testSchemeMatching_isCaseSensitive() { // Android URI schemes are case-sensitive - Uri correctScheme = Uri.parse("ca.bc.gov.asago://callback"); - Uri wrongCaseScheme = Uri.parse("CA.BC.GOV.ASAGO://callback"); + Uri correctScheme = Uri.parse(authUri("callback")); + Uri wrongCaseScheme = Uri.parse(AUTH_REDIRECT_SCHEME.toUpperCase() + "://callback"); - assertEquals("ca.bc.gov.asago", correctScheme.getScheme()); - assertNotEquals("ca.bc.gov.asago", wrongCaseScheme.getScheme()); + assertEquals(AUTH_REDIRECT_SCHEME, correctScheme.getScheme()); + assertNotEquals(AUTH_REDIRECT_SCHEME, wrongCaseScheme.getScheme()); } @Test public void testMultipleQueryParameters_canBeExtracted() { - Uri uri = Uri.parse("ca.bc.gov.asago://callback?code=abc&state=xyz&session_state=123"); + Uri uri = Uri.parse(authUri("callback?code=abc&state=xyz&session_state=123")); assertEquals("abc", uri.getQueryParameter("code")); assertEquals("xyz", uri.getQueryParameter("state")); @@ -173,9 +178,9 @@ public void testMultipleQueryParameters_canBeExtracted() { @Test public void testUriWithFragment_preservesFragment() { - Uri uri = Uri.parse("ca.bc.gov.asago://callback?code=test#fragment"); + Uri uri = Uri.parse(authUri("callback?code=test#fragment")); - assertEquals("ca.bc.gov.asago", uri.getScheme()); + assertEquals(AUTH_REDIRECT_SCHEME, uri.getScheme()); assertEquals("test", uri.getQueryParameter("code")); assertEquals("fragment", uri.getFragment()); } @@ -188,7 +193,7 @@ public void testHandleAuthorizationResponse_isCalledWithIntent() { mockedStatic.when(KeycloakPlugin::getInstance).thenReturn(mockPlugin); Intent intent = new Intent(); - intent.setData(Uri.parse("ca.bc.gov.asago://callback")); + intent.setData(Uri.parse(authUri("callback"))); KeycloakPlugin plugin = KeycloakPlugin.getInstance(); if (plugin != null) { @@ -202,7 +207,7 @@ public void testHandleAuthorizationResponse_isCalledWithIntent() { @Test public void testActivitySchemeConstant() { // Verify the expected scheme matches what's in AndroidManifest - String expectedScheme = "ca.bc.gov.asago"; + String expectedScheme = AUTH_REDIRECT_SCHEME; Uri uri = Uri.parse(expectedScheme + "://callback"); assertEquals(expectedScheme, uri.getScheme()); @@ -227,15 +232,15 @@ public void testPluginHandlesMultipleCallbacks() { try (MockedStatic mockedStatic = mockStatic(KeycloakPlugin.class)) { mockedStatic.when(KeycloakPlugin::getInstance).thenReturn(mockPlugin); - Uri uri1 = Uri.parse("ca.bc.gov.asago://callback?code=code1"); - Uri uri2 = Uri.parse("ca.bc.gov.asago://callback?code=code2"); + Uri uri1 = Uri.parse(authUri("callback?code=code1")); + Uri uri2 = Uri.parse(authUri("callback?code=code2")); KeycloakPlugin plugin = KeycloakPlugin.getInstance(); if (plugin != null) { - if ("ca.bc.gov.asago".equals(uri1.getScheme())) { + if (AUTH_REDIRECT_SCHEME.equals(uri1.getScheme())) { plugin.handleAuthCallback(uri1); } - if ("ca.bc.gov.asago".equals(uri2.getScheme())) { + if (AUTH_REDIRECT_SCHEME.equals(uri2.getScheme())) { plugin.handleAuthCallback(uri2); } } @@ -246,10 +251,10 @@ public void testPluginHandlesMultipleCallbacks() { @Test public void testUriPreservation_fullUriString() { - String uriString = "ca.bc.gov.asago://auth/callback?code=abc&state=xyz&session_state=123"; + String uriString = authUri("auth/callback?code=abc&state=xyz&session_state=123"); Uri uri = Uri.parse(uriString); - assertEquals("ca.bc.gov.asago", uri.getScheme()); + assertEquals(AUTH_REDIRECT_SCHEME, uri.getScheme()); // In custom schemes, the authority/host is "auth" and path is "/callback" assertEquals("/callback", uri.getPath()); assertEquals("code=abc&state=xyz&session_state=123", uri.getQuery()); diff --git a/mobile/asa-go/capacitor.config.ts b/mobile/asa-go/capacitor.config.ts index 6c361b61e2..04a6b9c50b 100644 --- a/mobile/asa-go/capacitor.config.ts +++ b/mobile/asa-go/capacitor.config.ts @@ -1,10 +1,18 @@ import type { CapacitorConfig } from "@capacitor/cli"; +const mode = process.env.APP_ENV ?? "prod"; +const isDev = mode === "dev"; + const config: CapacitorConfig = { - appId: "ca.bc.gov.asago", - appName: "asa-go", + appId: isDev ? "ca.bc.gov.asago.dev" : "ca.bc.gov.asago", + appName: isDev ? "ASA Go Dev" : "ASA Go", webDir: "dist", - ios: { scheme: "ASA Go" }, + android: { + flavor: isDev ? "dev" : "prod", + }, + ios: { + scheme: isDev ? "ASA Go dev" : "ASA Go", + }, plugins: { FirebaseMessaging: { presentationOptions: ["alert", "badge", "sound"], // iOS only diff --git a/mobile/asa-go/ios/App/ASA Go dev-Info.plist b/mobile/asa-go/ios/App/ASA Go dev-Info.plist new file mode 100644 index 0000000000..a4fca128a4 --- /dev/null +++ b/mobile/asa-go/ios/App/ASA Go dev-Info.plist @@ -0,0 +1,72 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ASA Go Dev + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleURLTypes + + + CFBundleURLName + ca.bc.gov.asago.auth + CFBundleURLSchemes + + ca.bc.gov.asago + + + + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + ITSAppUsesNonExemptEncryption + + LSRequiresIPhoneOS + + NSDocumentsFolderUsageDescription + Your app requires access to the Documents folder for file management. + NSLocationAlwaysAndWhenInUseUsageDescription + This app needs location access to show your position and provide location-based fire advisory information. + NSLocationWhenInUseUsageDescription + This app needs location access to show your position and provide location-based fire advisory information. + UIBackgroundModes + + remote-notification + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/mobile/asa-go/ios/App/App.xcodeproj/project.pbxproj b/mobile/asa-go/ios/App/App.xcodeproj/project.pbxproj index 2e744a46c1..9fa6a2a9e9 100644 --- a/mobile/asa-go/ios/App/App.xcodeproj/project.pbxproj +++ b/mobile/asa-go/ios/App/App.xcodeproj/project.pbxproj @@ -3,11 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 48; objects = { /* Begin PBXBuildFile section */ 2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; }; + 3051119718597F082FD266F3 /* Pods_ASA_Go.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0146A60730585B7E7BDD0243 /* Pods_ASA_Go.framework */; }; 4309C9DBE16C4DF38D493C6C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 1E60787A749448FB8E269E5A /* PrivacyInfo.xcprivacy */; }; 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; }; 504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; }; @@ -15,11 +16,23 @@ 504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; }; 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; }; 50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; }; - 5D93CF492F57402300551A11 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5D93CF482F57402300551A11 /* GoogleService-Info.plist */; }; - D51D96E4043C4B4AB92C9174 /* Pods_ASA_Go.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEB1CB68C85A338353E59F87 /* Pods_ASA_Go.framework */; }; + A511FA762F630E36007AD49F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; }; + A511FA7A2F630E36007AD49F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; }; + A511FA7C2F630E36007AD49F /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; }; + A511FA7D2F630E36007AD49F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; }; + A511FA7E2F630E36007AD49F /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; }; + A511FA7F2F630E36007AD49F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; }; + A511FA802F630E36007AD49F /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; }; + A511FA812F630E36007AD49F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 1E60787A749448FB8E269E5A /* PrivacyInfo.xcprivacy */; }; + A511FA8D2F631843007AD49F /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = A511FA8C2F631843007AD49F /* GoogleService-Info.plist */; }; + A511FA8F2F631858007AD49F /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = A511FA8E2F631858007AD49F /* GoogleService-Info.plist */; }; + D51D96E4043C4B4AB92C9174 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; + E67A8FADD0932A76EAA6E545 /* Pods_ASA_Go_dev.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CBC484E614E4BE483813586 /* Pods_ASA_Go_dev.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 0146A60730585B7E7BDD0243 /* Pods_ASA_Go.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ASA_Go.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1CBC484E614E4BE483813586 /* Pods_ASA_Go_dev.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ASA_Go_dev.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1E60787A749448FB8E269E5A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = ""; }; 50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = ""; }; @@ -30,10 +43,14 @@ 504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = ""; }; - 5D93CF482F57402300551A11 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 51207C9C622B9020DC600D92 /* Pods-ASA Go dev.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go dev.release.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go dev/Pods-ASA Go dev.release.xcconfig"; sourceTree = ""; }; + 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go dev.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go dev.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go dev/Pods-ASA Go dev.debug.xcconfig"; sourceTree = ""; }; 6654B5E52E29AC1C000DA498 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = ""; }; + A511FA862F630E36007AD49F /* ASA Go dev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ASA Go dev.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + A511FA872F630E36007AD49F /* ASA Go dev-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "ASA Go dev-Info.plist"; path = "/Users/breedwar/projects/other/wps/mobile/asa-go/ios/App/ASA Go dev-Info.plist"; sourceTree = ""; }; + A511FA8C2F631843007AD49F /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Firebase/Prod/GoogleService-Info.plist"; sourceTree = ""; }; + A511FA8E2F631858007AD49F /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Firebase/Dev/GoogleService-Info.plist"; sourceTree = ""; }; AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = ""; }; - BEB1CB68C85A338353E59F87 /* Pods_ASA_Go.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ASA_Go.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E5BF8FB19E4A8C9DE7D16845 /* Pods-ASA Go.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go.release.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go/Pods-ASA Go.release.xcconfig"; sourceTree = ""; }; F476C89842489D0CE7665883 /* Pods-ASA Go.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go/Pods-ASA Go.debug.xcconfig"; sourceTree = ""; }; FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = ""; }; @@ -44,7 +61,16 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D51D96E4043C4B4AB92C9174 /* Pods_ASA_Go.framework in Frameworks */, + D51D96E4043C4B4AB92C9174 /* BuildFile in Frameworks */, + 3051119718597F082FD266F3 /* Pods_ASA_Go.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A511FA772F630E36007AD49F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E67A8FADD0932A76EAA6E545 /* Pods_ASA_Go_dev.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -54,7 +80,8 @@ 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = { isa = PBXGroup; children = ( - BEB1CB68C85A338353E59F87 /* Pods_ASA_Go.framework */, + 1CBC484E614E4BE483813586 /* Pods_ASA_Go_dev.framework */, + 0146A60730585B7E7BDD0243 /* Pods_ASA_Go.framework */, ); name = Frameworks; sourceTree = ""; @@ -67,6 +94,7 @@ 7F8756D8B27F46E3366F6CEA /* Pods */, 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */, 1E60787A749448FB8E269E5A /* PrivacyInfo.xcprivacy */, + A511FA872F630E36007AD49F /* ASA Go dev-Info.plist */, ); sourceTree = ""; }; @@ -74,6 +102,7 @@ isa = PBXGroup; children = ( 504EC3041FED79650016851F /* ASA Go.app */, + A511FA862F630E36007AD49F /* ASA Go dev.app */, ); name = Products; sourceTree = ""; @@ -81,7 +110,8 @@ 504EC3061FED79650016851F /* App */ = { isa = PBXGroup; children = ( - 5D93CF482F57402300551A11 /* GoogleService-Info.plist */, + A511FA8E2F631858007AD49F /* GoogleService-Info.plist */, + A511FA8C2F631843007AD49F /* GoogleService-Info.plist */, 6654B5E52E29AC1C000DA498 /* App.entitlements */, 50379B222058CBB4000EE86E /* capacitor.config.json */, 504EC3071FED79650016851F /* AppDelegate.swift */, @@ -102,6 +132,8 @@ AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */, F476C89842489D0CE7665883 /* Pods-ASA Go.debug.xcconfig */, E5BF8FB19E4A8C9DE7D16845 /* Pods-ASA Go.release.xcconfig */, + 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go dev.debug.xcconfig */, + 51207C9C622B9020DC600D92 /* Pods-ASA Go dev.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -128,6 +160,25 @@ productReference = 504EC3041FED79650016851F /* ASA Go.app */; productType = "com.apple.product-type.application"; }; + A511FA732F630E36007AD49F /* ASA Go dev */ = { + isa = PBXNativeTarget; + buildConfigurationList = A511FA832F630E36007AD49F /* Build configuration list for PBXNativeTarget "ASA Go dev" */; + buildPhases = ( + A511FA742F630E36007AD49F /* [CP] Check Pods Manifest.lock */, + A511FA752F630E36007AD49F /* Sources */, + A511FA772F630E36007AD49F /* Frameworks */, + A511FA792F630E36007AD49F /* Resources */, + A511FA822F630E36007AD49F /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "ASA Go dev"; + productName = App; + productReference = A511FA862F630E36007AD49F /* ASA Go dev.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -142,6 +193,9 @@ LastSwiftMigration = 1100; ProvisioningStyle = Automatic; }; + A511FA732F630E36007AD49F = { + ProvisioningStyle = Automatic; + }; }; }; buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */; @@ -158,6 +212,7 @@ projectRoot = ""; targets = ( 504EC3031FED79650016851F /* ASA Go */, + A511FA732F630E36007AD49F /* ASA Go dev */, ); }; /* End PBXProject section */ @@ -168,7 +223,7 @@ buildActionMask = 2147483647; files = ( 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */, - 5D93CF492F57402300551A11 /* GoogleService-Info.plist in Resources */, + A511FA8D2F631843007AD49F /* GoogleService-Info.plist in Resources */, 50B271D11FEDC1A000F3C39B /* public in Resources */, 504EC30F1FED79650016851F /* Assets.xcassets in Resources */, 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */, @@ -178,6 +233,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + A511FA792F630E36007AD49F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A511FA7A2F630E36007AD49F /* LaunchScreen.storyboard in Resources */, + A511FA8F2F631858007AD49F /* GoogleService-Info.plist in Resources */, + A511FA7C2F630E36007AD49F /* public in Resources */, + A511FA7D2F630E36007AD49F /* Assets.xcassets in Resources */, + A511FA7E2F630E36007AD49F /* capacitor.config.json in Resources */, + A511FA7F2F630E36007AD49F /* Main.storyboard in Resources */, + A511FA802F630E36007AD49F /* config.xml in Resources */, + A511FA812F630E36007AD49F /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -214,6 +284,39 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ASA Go/Pods-ASA Go-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + A511FA742F630E36007AD49F /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ASA Go dev-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + A511FA822F630E36007AD49F /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ASA Go dev/Pods-ASA Go dev-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -225,6 +328,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + A511FA752F630E36007AD49F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A511FA762F630E36007AD49F /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ @@ -349,8 +460,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 14.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -366,10 +476,7 @@ DEVELOPMENT_TEAM = L796QSLV3E; INFOPLIST_FILE = App/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = ca.bc.gov.asago; @@ -393,10 +500,7 @@ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = L796QSLV3E; INFOPLIST_FILE = App/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = ca.bc.gov.asago; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -407,6 +511,53 @@ }; name = Release; }; + A511FA842F630E36007AD49F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go dev.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = App/App.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = L796QSLV3E; + INFOPLIST_FILE = "ASA Go dev-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MARKETING_VERSION = 1.0; + OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; + PRODUCT_BUNDLE_IDENTIFIER = ca.bc.gov.asago.dev; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + A511FA852F630E36007AD49F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51207C9C622B9020DC600D92 /* Pods-ASA Go dev.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = App/App.entitlements; + CODE_SIGN_IDENTITY = "Apple Distribution: Government of British Columbia (L796QSLV3E)"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = L796QSLV3E; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = L796QSLV3E; + INFOPLIST_FILE = "ASA Go dev-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = ca.bc.gov.asago.dev; + "PRODUCT_BUNDLE_IDENTIFIER[sdk=*]" = ca.bc.gov.asago.dev; + PRODUCT_NAME = "$(TARGET_NAME)"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "ASA Go"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -428,8 +579,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + A511FA832F630E36007AD49F /* Build configuration list for PBXNativeTarget "ASA Go dev" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A511FA842F630E36007AD49F /* Debug */, + A511FA852F630E36007AD49F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ - }; rootObject = 504EC2FC1FED79650016851F /* Project object */; } diff --git a/mobile/asa-go/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved b/mobile/asa-go/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index b50a21402d..0000000000 --- a/mobile/asa-go/ios/App/App.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,123 +0,0 @@ -{ - "originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329", - "pins" : [ - { - "identity" : "abseil-cpp-binary", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/abseil-cpp-binary.git", - "state" : { - "revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5", - "version" : "1.2024072200.0" - } - }, - { - "identity" : "app-check", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/app-check.git", - "state" : { - "revision" : "61b85103a1aeed8218f17c794687781505fbbef5", - "version" : "11.2.0" - } - }, - { - "identity" : "firebase-ios-sdk", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/firebase-ios-sdk", - "state" : { - "revision" : "85560b48b0ff099ad83fe53d67df3c67fbc2b7a6", - "version" : "12.10.0" - } - }, - { - "identity" : "google-ads-on-device-conversion-ios-sdk", - "kind" : "remoteSourceControl", - "location" : "https://github.com/googleads/google-ads-on-device-conversion-ios-sdk", - "state" : { - "revision" : "a5cd95c80e8efdd02155c6cea1cecf743bb683a5", - "version" : "3.3.0" - } - }, - { - "identity" : "googleappmeasurement", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/GoogleAppMeasurement.git", - "state" : { - "revision" : "68ba955e540dcff5e0805970ef4b1fd0150be100", - "version" : "12.10.0" - } - }, - { - "identity" : "googledatatransport", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/GoogleDataTransport.git", - "state" : { - "revision" : "617af071af9aa1d6a091d59a202910ac482128f9", - "version" : "10.1.0" - } - }, - { - "identity" : "googleutilities", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/GoogleUtilities.git", - "state" : { - "revision" : "60da361632d0de02786f709bdc0c4df340f7613e", - "version" : "8.1.0" - } - }, - { - "identity" : "grpc-binary", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/grpc-binary.git", - "state" : { - "revision" : "75b31c842f664a0f46a2e590a570e370249fd8f6", - "version" : "1.69.1" - } - }, - { - "identity" : "gtm-session-fetcher", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/gtm-session-fetcher.git", - "state" : { - "revision" : "a883ddb9fd464216133a5ab441f1ae8995978573", - "version" : "5.1.0" - } - }, - { - "identity" : "interop-ios-for-google-sdks", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/interop-ios-for-google-sdks.git", - "state" : { - "revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe", - "version" : "101.0.0" - } - }, - { - "identity" : "leveldb", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/leveldb.git", - "state" : { - "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", - "version" : "1.22.5" - } - }, - { - "identity" : "nanopb", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/nanopb.git", - "state" : { - "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", - "version" : "2.30910.0" - } - }, - { - "identity" : "promises", - "kind" : "remoteSourceControl", - "location" : "https://github.com/google/promises.git", - "state" : { - "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", - "version" : "2.4.0" - } - } - ], - "version" : 3 -} diff --git a/mobile/asa-go/ios/App/Podfile b/mobile/asa-go/ios/App/Podfile index e9e386b1a2..4f2b62609d 100644 --- a/mobile/asa-go/ios/App/Podfile +++ b/mobile/asa-go/ios/App/Podfile @@ -33,6 +33,12 @@ target 'ASA Go' do # Add your Pods here end +target 'ASA Go dev' do + capacitor_pods + pod 'FirebaseMessaging' + # Add your Pods here +end + post_install do |installer| assertDeploymentTarget(installer) end diff --git a/mobile/asa-go/ios/App/Podfile.lock b/mobile/asa-go/ios/App/Podfile.lock index 13c2b441ce..8d8ba0cdf8 100644 --- a/mobile/asa-go/ios/App/Podfile.lock +++ b/mobile/asa-go/ios/App/Podfile.lock @@ -165,21 +165,21 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: AppAuth: 1c1a8afa7e12f2ec3a294d9882dfa5ab7d3cb063 - Capacitor: 68ff8eabbcce387e69767c13b5fbcc1c5399eabc - CapacitorApp: 45cb7cbef4aa380b9236fd6980033eb5cde6fcd2 + Capacitor: bceb785fb78f5e81e4a9e37843bc1c24bd9c7194 + CapacitorApp: 9cb31064a6c6bb2b1438583733a7bf45557fc1da CapacitorCordova: 866217f32c1d25b326c568a10ea3ed0c36b13e29 - CapacitorDevice: ebd210e29ae690225291b8616e6cfaf419d2e866 - CapacitorEmailComposer: 6e06f75898334036cc95ada2238b3dcbb78932c0 - CapacitorFilesystem: f54cd6b76be06fa7ceb219cf313d32e0d626ea87 - CapacitorFirebaseMessaging: 798b7f8af4318b97b11eb9b84c8ebe9920237c17 - CapacitorGeolocation: de4b0ccf90140528184e31676dd5e3a328eb589a - CapacitorHaptics: 1fba3e460e7614349c6d5f868b1fccdc5c87b66d - CapacitorKeyboard: 2c26c6fccde35023c579fc37d4cae6326d5e6343 - CapacitorNetwork: 3d56050f929a8c86427a5b28558ce605e7cf61b3 - CapacitorPreferences: d82a7e3b95fcab43a553268b803356522910d153 - CapacitorScreenOrientation: 07503c9d633377427f1e122449b06b1dbc992d10 - CapacitorSplashScreen: b3d12b4324d93ce605fe57f05a199ade7f26189e - CapacitorStatusBar: 438e90beeeefa8276b24e6c5991cb02dd13e51bf + CapacitorDevice: ff033fa0c4ec19f5e059a073769a9b2347e69f57 + CapacitorEmailComposer: 47e488b85f3a4400e3b616fe56b5b9f65a4aa2f3 + CapacitorFilesystem: c63fc54df41e5a6761785a7f3c49dc696c22e296 + CapacitorFirebaseMessaging: 000e9eb39f2cebcf89afeff5c9e056980ed0014e + CapacitorGeolocation: ab54d708e2fcf99a7bafe0219eaa6f7a932f001a + CapacitorHaptics: 7be406a91e4eb87287f321c6c68e1709d6837b3a + CapacitorKeyboard: 4db71e694e7afb5d7c0be09b05495c19f7d6c914 + CapacitorNetwork: b719d692a8d1310da8d26d6648d3aa1ef1e100e1 + CapacitorPreferences: 69d9991307507aeab8ef8019c10b9babfda0e9ca + CapacitorScreenOrientation: 6c3c84223ea1dd44aaa7184e2b416dd1192270d0 + CapacitorSplashScreen: 409eeaaeac603d264f209c0fcb718aa22fe1f7bb + CapacitorStatusBar: a8c4c83ed2e973bdafb979e80e4b00d027832cb7 FirebaseCore: c7b57863ce0859281a66d16ca36d665c45d332b5 FirebaseCoreInternal: 571a2dd8c975410966199623351db3a3265c874d FirebaseInstallations: 6d05424a046b68ca146b4de4376f05b4e9262fc3 @@ -188,10 +188,10 @@ SPEC CHECKSUMS: GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 IONFilesystemLib: dfa8706539ac9ab77ccfd6e5b3830ce9b5e57f6c IONGeolocationLib: 20f9d0248a0b5264511fb57a37e25dd2badf797a - Keycloak: c39abe3ec71f672fbf306a7f37b85d3858ae7f00 + Keycloak: ed7f0a99e83d402ed7bb91a5f5d15fa0249b6928 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 -PODFILE CHECKSUM: 628b81ca6723b5813c3d45a730d7dc8d60765b92 +PODFILE CHECKSUM: f85f8dbcd8b6731ed82c650c697ec343a8619f28 COCOAPODS: 1.16.2 diff --git a/mobile/asa-go/package.json b/mobile/asa-go/package.json index 6a118ffe48..7b81901dbd 100644 --- a/mobile/asa-go/package.json +++ b/mobile/asa-go/package.json @@ -13,7 +13,11 @@ "build:dev": "vite build --mode development", "build:prod": "vite build --mode production", "cap:sync:dev": "yarn build:dev && yarn cap sync", - "cap:sync:prod": "yarn build:prod && yarn cap sync" + "cap:sync:prod": "yarn build:prod && yarn cap sync", + "cap:sync:android:dev": "APP_ENV=dev yarn build:dev && yarn cap sync android", + "cap:sync:android:prod": "APP_ENV=prod yarn build:prod && yarn cap sync android", + "cap:sync:ios:dev": "APP_ENV=dev yarn build:dev && yarn cap sync ios", + "cap:sync:ios:prod": "APP_ENV=prod yarn build:prod && yarn cap sync ios" }, "dependencies": { "@capacitor-firebase/messaging": "^8.1.0", @@ -66,6 +70,7 @@ "@types/jest": "^30.0.0", "@types/lodash": "^4.17.14", "@types/luxon": "^3.4.2", + "@types/node": "^25.5.0", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@types/sinon": "^21.0.0", diff --git a/mobile/asa-go/tsconfig.node.json b/mobile/asa-go/tsconfig.node.json index db0becc8b0..6a2082779e 100644 --- a/mobile/asa-go/tsconfig.node.json +++ b/mobile/asa-go/tsconfig.node.json @@ -4,6 +4,7 @@ "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", + "types": ["node"], "skipLibCheck": true, /* Bundler mode */ @@ -20,5 +21,5 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["vite.config.ts"] + "include": ["vite.config.ts", "capacitor.config.ts"] } diff --git a/mobile/asa-go/yarn.lock b/mobile/asa-go/yarn.lock index 620eb0e1d0..fddd8c77a8 100644 --- a/mobile/asa-go/yarn.lock +++ b/mobile/asa-go/yarn.lock @@ -2095,6 +2095,13 @@ dependencies: undici-types "~7.18.0" +"@types/node@^25.5.0": + version "25.5.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-25.5.0.tgz#5c99f37c443d9ccc4985866913f1ed364217da31" + integrity sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw== + dependencies: + undici-types "~7.18.0" + "@types/normalize-package-data@^2.4.0": version "2.4.4" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" From f35598cbdf28c83a7ed418d996c198e13a6fda55 Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Mon, 16 Mar 2026 11:07:59 -0700 Subject: [PATCH 02/18] dev&prod scripts --- mobile/asa-go/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/asa-go/package.json b/mobile/asa-go/package.json index 7b81901dbd..0f92339a5b 100644 --- a/mobile/asa-go/package.json +++ b/mobile/asa-go/package.json @@ -12,8 +12,8 @@ "preview": "vite preview", "build:dev": "vite build --mode development", "build:prod": "vite build --mode production", - "cap:sync:dev": "yarn build:dev && yarn cap sync", - "cap:sync:prod": "yarn build:prod && yarn cap sync", + "cap:sync:dev": "APP_ENV=dev yarn build:dev && yarn cap sync", + "cap:sync:prod": "APP_ENV=prod yarn build:prod && yarn cap sync", "cap:sync:android:dev": "APP_ENV=dev yarn build:dev && yarn cap sync android", "cap:sync:android:prod": "APP_ENV=prod yarn build:prod && yarn cap sync android", "cap:sync:ios:dev": "APP_ENV=dev yarn build:dev && yarn cap sync ios", From a566d7803c824c0666c8b942e3cf9bf644ed97d7 Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Mon, 16 Mar 2026 14:49:21 -0700 Subject: [PATCH 03/18] test prod --- mobile/asa-go/android/app/build.gradle | 27 +++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/mobile/asa-go/android/app/build.gradle b/mobile/asa-go/android/app/build.gradle index f54fda8595..f0dc18d71f 100644 --- a/mobile/asa-go/android/app/build.gradle +++ b/mobile/asa-go/android/app/build.gradle @@ -1,6 +1,5 @@ apply plugin: 'com.android.application' apply plugin: 'jacoco' -apply plugin: 'com.google.gms.google-services' android { namespace "ca.bc.gov.asago" @@ -99,20 +98,26 @@ tasks.withType(Test) { jacoco.excludes = ['jdk.internal.*'] } -task jacocoTestReport(type: JacocoReport, dependsOn: ['testDevDebugUnitTest', 'testProdDebugUnitTest']) { +task jacocoTestReport(type: JacocoReport, dependsOn: ['testProdDebugUnitTest']) { reports { xml.required = true html.required = false } def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*'] - def debugTrees = files( - fileTree(dir: "${buildDir}/intermediates/javac/devDebug/compileDevDebugJavaWithJavac/classes", excludes: fileFilter), - fileTree(dir: "${buildDir}/intermediates/javac/prodDebug/compileProdDebugJavaWithJavac/classes", excludes: fileFilter) - ) + def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/prodDebug/compileProdDebugJavaWithJavac/classes", excludes: fileFilter) sourceDirectories.setFrom(files(["${project.projectDir}/src/main/java"])) - classDirectories.setFrom(debugTrees) - executionData.setFrom(fileTree(dir: "$buildDir", includes: [ - "jacoco/testDevDebugUnitTest.exec", - "jacoco/testProdDebugUnitTest.exec" - ])) + classDirectories.setFrom(files([debugTree])) + executionData.setFrom(fileTree(dir: "$buildDir", includes: ["jacoco/testProdDebugUnitTest.exec"])) +} + +try { + def googleServicesFiles = [ + file('src/dev/google-services.json'), + file('src/prod/google-services.json') + ] + if (googleServicesFiles.any { it.exists() && it.text.trim() }) { + apply plugin: 'com.google.gms.google-services' + } +} catch(Exception e) { + logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") } From 556e93669fc75c7d8ec7b4a455fac7b515c674dc Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 09:12:42 -0700 Subject: [PATCH 04/18] new target --- mobile/asa-go/capacitor.config.ts | 4 +- .../ios/App/App.xcodeproj/project.pbxproj | 48 +++++++++---------- .../asa-go/ios/App/App/Firebase/Dev/.gitkeep | 0 .../asa-go/ios/App/App/Firebase/Prod/.gitkeep | 0 .../dev-Info.plist} | 2 +- mobile/asa-go/ios/App/Podfile | 2 +- mobile/asa-go/package.json | 12 ++--- 7 files changed, 34 insertions(+), 34 deletions(-) create mode 100644 mobile/asa-go/ios/App/App/Firebase/Dev/.gitkeep create mode 100644 mobile/asa-go/ios/App/App/Firebase/Prod/.gitkeep rename mobile/asa-go/ios/App/{ASA Go dev-Info.plist => App/dev-Info.plist} (98%) diff --git a/mobile/asa-go/capacitor.config.ts b/mobile/asa-go/capacitor.config.ts index 04a6b9c50b..3473f28eff 100644 --- a/mobile/asa-go/capacitor.config.ts +++ b/mobile/asa-go/capacitor.config.ts @@ -1,6 +1,6 @@ import type { CapacitorConfig } from "@capacitor/cli"; -const mode = process.env.APP_ENV ?? "prod"; +const mode = process.env.APP_ENV ?? "dev"; const isDev = mode === "dev"; const config: CapacitorConfig = { @@ -11,7 +11,7 @@ const config: CapacitorConfig = { flavor: isDev ? "dev" : "prod", }, ios: { - scheme: isDev ? "ASA Go dev" : "ASA Go", + scheme: isDev ? "ASA Go Dev" : "ASA Go", }, plugins: { FirebaseMessaging: { diff --git a/mobile/asa-go/ios/App/App.xcodeproj/project.pbxproj b/mobile/asa-go/ios/App/App.xcodeproj/project.pbxproj index 9fa6a2a9e9..a0f05b14f7 100644 --- a/mobile/asa-go/ios/App/App.xcodeproj/project.pbxproj +++ b/mobile/asa-go/ios/App/App.xcodeproj/project.pbxproj @@ -26,13 +26,12 @@ A511FA812F630E36007AD49F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 1E60787A749448FB8E269E5A /* PrivacyInfo.xcprivacy */; }; A511FA8D2F631843007AD49F /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = A511FA8C2F631843007AD49F /* GoogleService-Info.plist */; }; A511FA8F2F631858007AD49F /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = A511FA8E2F631858007AD49F /* GoogleService-Info.plist */; }; + ABA9EE54FF69B84C1D8E12CA /* Pods_ASA_Go_Dev.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8A4D9A6B1370E8B40A3B42E /* Pods_ASA_Go_Dev.framework */; }; D51D96E4043C4B4AB92C9174 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; - E67A8FADD0932A76EAA6E545 /* Pods_ASA_Go_dev.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CBC484E614E4BE483813586 /* Pods_ASA_Go_dev.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 0146A60730585B7E7BDD0243 /* Pods_ASA_Go.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ASA_Go.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 1CBC484E614E4BE483813586 /* Pods_ASA_Go_dev.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ASA_Go_dev.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1E60787A749448FB8E269E5A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = ""; }; 50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = ""; }; @@ -43,16 +42,17 @@ 504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = ""; }; - 51207C9C622B9020DC600D92 /* Pods-ASA Go dev.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go dev.release.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go dev/Pods-ASA Go dev.release.xcconfig"; sourceTree = ""; }; - 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go dev.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go dev.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go dev/Pods-ASA Go dev.debug.xcconfig"; sourceTree = ""; }; + 51207C9C622B9020DC600D92 /* Pods-ASA Go Dev.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go Dev.release.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go Dev/Pods-ASA Go Dev.release.xcconfig"; sourceTree = ""; }; + 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go Dev.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go Dev.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go Dev/Pods-ASA Go Dev.debug.xcconfig"; sourceTree = ""; }; 6654B5E52E29AC1C000DA498 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = ""; }; - A511FA862F630E36007AD49F /* ASA Go dev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ASA Go dev.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - A511FA872F630E36007AD49F /* ASA Go dev-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "ASA Go dev-Info.plist"; path = "/Users/breedwar/projects/other/wps/mobile/asa-go/ios/App/ASA Go dev-Info.plist"; sourceTree = ""; }; + A511FA862F630E36007AD49F /* ASA Go Dev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ASA Go Dev.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + A511FA872F630E36007AD49F /* dev-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "dev-Info.plist"; sourceTree = ""; }; A511FA8C2F631843007AD49F /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Firebase/Prod/GoogleService-Info.plist"; sourceTree = ""; }; A511FA8E2F631858007AD49F /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Firebase/Dev/GoogleService-Info.plist"; sourceTree = ""; }; AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = ""; }; E5BF8FB19E4A8C9DE7D16845 /* Pods-ASA Go.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go.release.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go/Pods-ASA Go.release.xcconfig"; sourceTree = ""; }; F476C89842489D0CE7665883 /* Pods-ASA Go.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASA Go.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ASA Go/Pods-ASA Go.debug.xcconfig"; sourceTree = ""; }; + F8A4D9A6B1370E8B40A3B42E /* Pods_ASA_Go_Dev.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ASA_Go_Dev.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -70,7 +70,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E67A8FADD0932A76EAA6E545 /* Pods_ASA_Go_dev.framework in Frameworks */, + ABA9EE54FF69B84C1D8E12CA /* Pods_ASA_Go_Dev.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -80,8 +80,8 @@ 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = { isa = PBXGroup; children = ( - 1CBC484E614E4BE483813586 /* Pods_ASA_Go_dev.framework */, 0146A60730585B7E7BDD0243 /* Pods_ASA_Go.framework */, + F8A4D9A6B1370E8B40A3B42E /* Pods_ASA_Go_Dev.framework */, ); name = Frameworks; sourceTree = ""; @@ -94,7 +94,6 @@ 7F8756D8B27F46E3366F6CEA /* Pods */, 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */, 1E60787A749448FB8E269E5A /* PrivacyInfo.xcprivacy */, - A511FA872F630E36007AD49F /* ASA Go dev-Info.plist */, ); sourceTree = ""; }; @@ -102,7 +101,7 @@ isa = PBXGroup; children = ( 504EC3041FED79650016851F /* ASA Go.app */, - A511FA862F630E36007AD49F /* ASA Go dev.app */, + A511FA862F630E36007AD49F /* ASA Go Dev.app */, ); name = Products; sourceTree = ""; @@ -119,6 +118,7 @@ 504EC30E1FED79650016851F /* Assets.xcassets */, 504EC3101FED79650016851F /* LaunchScreen.storyboard */, 504EC3131FED79650016851F /* Info.plist */, + A511FA872F630E36007AD49F /* dev-Info.plist */, 2FAD9762203C412B000D30F8 /* config.xml */, 50B271D01FEDC1A000F3C39B /* public */, ); @@ -132,8 +132,8 @@ AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */, F476C89842489D0CE7665883 /* Pods-ASA Go.debug.xcconfig */, E5BF8FB19E4A8C9DE7D16845 /* Pods-ASA Go.release.xcconfig */, - 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go dev.debug.xcconfig */, - 51207C9C622B9020DC600D92 /* Pods-ASA Go dev.release.xcconfig */, + 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go Dev.debug.xcconfig */, + 51207C9C622B9020DC600D92 /* Pods-ASA Go Dev.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -160,9 +160,9 @@ productReference = 504EC3041FED79650016851F /* ASA Go.app */; productType = "com.apple.product-type.application"; }; - A511FA732F630E36007AD49F /* ASA Go dev */ = { + A511FA732F630E36007AD49F /* ASA Go Dev */ = { isa = PBXNativeTarget; - buildConfigurationList = A511FA832F630E36007AD49F /* Build configuration list for PBXNativeTarget "ASA Go dev" */; + buildConfigurationList = A511FA832F630E36007AD49F /* Build configuration list for PBXNativeTarget "ASA Go Dev" */; buildPhases = ( A511FA742F630E36007AD49F /* [CP] Check Pods Manifest.lock */, A511FA752F630E36007AD49F /* Sources */, @@ -174,9 +174,9 @@ ); dependencies = ( ); - name = "ASA Go dev"; + name = "ASA Go Dev"; productName = App; - productReference = A511FA862F630E36007AD49F /* ASA Go dev.app */; + productReference = A511FA862F630E36007AD49F /* ASA Go Dev.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -212,7 +212,7 @@ projectRoot = ""; targets = ( 504EC3031FED79650016851F /* ASA Go */, - A511FA732F630E36007AD49F /* ASA Go dev */, + A511FA732F630E36007AD49F /* ASA Go Dev */, ); }; /* End PBXProject section */ @@ -295,7 +295,7 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ASA Go dev-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-ASA Go Dev-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -314,7 +314,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ASA Go dev/Pods-ASA Go dev-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ASA Go Dev/Pods-ASA Go Dev-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -513,14 +513,14 @@ }; A511FA842F630E36007AD49F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go dev.debug.xcconfig */; + baseConfigurationReference = 5DECCDBD9A33EE51D824DC98 /* Pods-ASA Go Dev.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = App/App.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = L796QSLV3E; - INFOPLIST_FILE = "ASA Go dev-Info.plist"; + INFOPLIST_FILE = "App/dev-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; @@ -535,7 +535,7 @@ }; A511FA852F630E36007AD49F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 51207C9C622B9020DC600D92 /* Pods-ASA Go dev.release.xcconfig */; + baseConfigurationReference = 51207C9C622B9020DC600D92 /* Pods-ASA Go Dev.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = App/App.entitlements; @@ -544,7 +544,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = L796QSLV3E; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = L796QSLV3E; - INFOPLIST_FILE = "ASA Go dev-Info.plist"; + INFOPLIST_FILE = "App/dev-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; @@ -579,7 +579,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - A511FA832F630E36007AD49F /* Build configuration list for PBXNativeTarget "ASA Go dev" */ = { + A511FA832F630E36007AD49F /* Build configuration list for PBXNativeTarget "ASA Go Dev" */ = { isa = XCConfigurationList; buildConfigurations = ( A511FA842F630E36007AD49F /* Debug */, diff --git a/mobile/asa-go/ios/App/App/Firebase/Dev/.gitkeep b/mobile/asa-go/ios/App/App/Firebase/Dev/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/mobile/asa-go/ios/App/App/Firebase/Prod/.gitkeep b/mobile/asa-go/ios/App/App/Firebase/Prod/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/mobile/asa-go/ios/App/ASA Go dev-Info.plist b/mobile/asa-go/ios/App/App/dev-Info.plist similarity index 98% rename from mobile/asa-go/ios/App/ASA Go dev-Info.plist rename to mobile/asa-go/ios/App/App/dev-Info.plist index a4fca128a4..13bb320d52 100644 --- a/mobile/asa-go/ios/App/ASA Go dev-Info.plist +++ b/mobile/asa-go/ios/App/App/dev-Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion en CFBundleDisplayName - ASA Go Dev + ASA Go dev CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier diff --git a/mobile/asa-go/ios/App/Podfile b/mobile/asa-go/ios/App/Podfile index 4f2b62609d..16a4313e7c 100644 --- a/mobile/asa-go/ios/App/Podfile +++ b/mobile/asa-go/ios/App/Podfile @@ -33,7 +33,7 @@ target 'ASA Go' do # Add your Pods here end -target 'ASA Go dev' do +target 'ASA Go Dev' do capacitor_pods pod 'FirebaseMessaging' # Add your Pods here diff --git a/mobile/asa-go/package.json b/mobile/asa-go/package.json index 0f92339a5b..54ae5aecf0 100644 --- a/mobile/asa-go/package.json +++ b/mobile/asa-go/package.json @@ -12,12 +12,12 @@ "preview": "vite preview", "build:dev": "vite build --mode development", "build:prod": "vite build --mode production", - "cap:sync:dev": "APP_ENV=dev yarn build:dev && yarn cap sync", - "cap:sync:prod": "APP_ENV=prod yarn build:prod && yarn cap sync", - "cap:sync:android:dev": "APP_ENV=dev yarn build:dev && yarn cap sync android", - "cap:sync:android:prod": "APP_ENV=prod yarn build:prod && yarn cap sync android", - "cap:sync:ios:dev": "APP_ENV=dev yarn build:dev && yarn cap sync ios", - "cap:sync:ios:prod": "APP_ENV=prod yarn build:prod && yarn cap sync ios" + "cap:sync:dev": "APP_ENV=dev yarn build:dev && APP_ENV=dev yarn cap sync", + "cap:sync:prod": "APP_ENV=prod yarn build:prod && APP_ENV=prod yarn cap sync", + "cap:sync:android:dev": "APP_ENV=dev yarn build:dev && APP_ENV=dev yarn cap sync android", + "cap:sync:android:prod": "APP_ENV=prod yarn build:prod && APP_ENV=prod yarn cap sync android", + "cap:sync:ios:dev": "APP_ENV=dev yarn build:dev && APP_ENV=dev yarn cap sync ios", + "cap:sync:ios:prod": "APP_ENV=prod yarn build:prod && APP_ENV=prod yarn cap sync ios" }, "dependencies": { "@capacitor-firebase/messaging": "^8.1.0", From d9a0678bcf68b2c4bd805242f4d34217557e14e2 Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 10:57:32 -0700 Subject: [PATCH 05/18] read me updates --- mobile/asa-go/Notifications.md | 4 +++- mobile/asa-go/README.md | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/mobile/asa-go/Notifications.md b/mobile/asa-go/Notifications.md index 8983dccb4b..aaff996fe7 100644 --- a/mobile/asa-go/Notifications.md +++ b/mobile/asa-go/Notifications.md @@ -85,7 +85,7 @@ In the app repo: - iOS bundle IDs - Android application IDs / flavors -- Xcode targets/schemes +- Xcode targets/schemes (`ASA Go` and `ASA Go Dev`) - `GoogleService-Info.plist` - `google-services.json` - Capacitor config @@ -140,6 +140,8 @@ APP_ENV=dev ionic capacitor run android -l --external APP_ENV=prod ionic capacitor run android -l --external ``` +On iOS, `APP_ENV=dev` selects the `ASA Go Dev` scheme and `APP_ENV=prod` selects `ASA Go`. + ## Quick checks If notifications are not working, check these first: diff --git a/mobile/asa-go/README.md b/mobile/asa-go/README.md index d132ad94d0..67c529c5e1 100644 --- a/mobile/asa-go/README.md +++ b/mobile/asa-go/README.md @@ -20,11 +20,6 @@ yarn install yarn build ``` -APP_ENV=dev ionic capacitor run ios -l --external -APP_ENV=prod ionic capacitor run ios -l --external -APP_ENV=dev ionic capacitor run android -l --external -APP_ENV=prod ionic capacitor run android -l --external - ## Setup live reload 1. Install ionic CLI and native run for live reload with: `npm install -g @ionic/cli native-run` @@ -34,7 +29,12 @@ APP_ENV=prod ionic capacitor run android -l --external 1. Make sure xcode is installed with `xcode-select --install` 2. Go to `mobile/asa-go` 3. Run `APP_ENV=dev yarn cap:sync:ios:dev` or `APP_ENV=prod yarn cap:sync:ios:prod` -4. Build and run with live reload: `APP_ENV=dev ionic capacitor run ios -l --external` or `APP_ENV=prod ionic capacitor run ios -l --external` +4. List available devices/simulators with `ionic capacitor run ios --list` +5. Build and run with live reload: + - `APP_ENV=dev ionic capacitor run ios -l --external` + - `APP_ENV=prod ionic capacitor run ios -l --external` + +`APP_ENV=dev` selects the `ASA Go Dev` iOS scheme and `APP_ENV=prod` selects `ASA Go`. ### Building/Running Android @@ -44,7 +44,12 @@ APP_ENV=prod ionic capacitor run android -l --external - Set `$ANDROID_HOME` to the path of the Android SDK 3. Go to `mobile/asa-go` 4. Run `APP_ENV=dev yarn cap:sync:android:dev` or `APP_ENV=prod yarn cap:sync:android:prod` -5. Build and run with live reload: `APP_ENV=dev ionic capacitor run android -l --external` or `APP_ENV=prod ionic capacitor run android -l --external` +5. If you are building from Android Studio, open the [`android`](/Users/breedwar/projects/other/wps/mobile/asa-go/android) project and choose the matching build variant in the `Build Variants` tool window: + - `devDebug` or `devRelease` after a dev sync + - `prodDebug` or `prodRelease` after a prod sync +6. Build and run with live reload: `APP_ENV=dev ionic capacitor run android -l --external` or `APP_ENV=prod ionic capacitor run android -l --external` + +If the selected Android Studio build variant does not match the last `cap sync` flavor, you can end up with mismatched native config and web assets. To build a debug APK directly: From eaa5b4e6e2887a6740d4c8d605641a425aa158df Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 11:21:46 -0700 Subject: [PATCH 06/18] clarity --- mobile/asa-go/Notifications.md | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/mobile/asa-go/Notifications.md b/mobile/asa-go/Notifications.md index aaff996fe7..2cda08938a 100644 --- a/mobile/asa-go/Notifications.md +++ b/mobile/asa-go/Notifications.md @@ -96,29 +96,14 @@ In Firebase Console: - Firebase app registration for each bundle ID - Cloud Messaging setup -## Auth callback scheme - -The Android dev and prod flavors currently share the same AppAuth redirect scheme: - -- `ca.bc.gov.asago` - -That matches the older auth setup. The app IDs are still different, but the auth callback scheme is shared. - -This is workable, but there is one tradeoff: if both Android app variants are installed on the same device, a custom-scheme auth callback can be ambiguous because both apps can claim the same scheme. - ## Why we use separate app IDs This repo uses separate app IDs for dev and prod instead of trying to inject only Firebase config into one app identity. -Why this is useful: +This lets dev and prod be installed on the same device at the same time. It also keeps dev push notifications separate from +prod and makes the Firebase app registration clearer, because each app variant has its own app ID. -- dev and prod can both be installed on the same iPhone -- dev and prod can both be installed on the same Android device -- dev push notifications stay separate from prod -- dev testing is less likely to affect the prod app -- the Firebase app registration is clearer because each app variant has its own app ID - -An alternative is to keep one app ID and inject different config at build time. That can work, but it means dev and prod are still the same app identity, so they cannot be installed side by side. +On iOS, the current implementation uses separate Xcode targets and separate `Info.plist` files for those app identities. ## Running dev vs prod @@ -141,13 +126,3 @@ APP_ENV=prod ionic capacitor run android -l --external ``` On iOS, `APP_ENV=dev` selects the `ASA Go Dev` scheme and `APP_ENV=prod` selects `ASA Go`. - -## Quick checks - -If notifications are not working, check these first: - -1. The installed app's iOS bundle ID or Android application ID matches the Firebase app config. -2. The correct `GoogleService-Info.plist` or `google-services.json` is included for the target/flavor. -3. APNs auth key is uploaded in the correct Firebase project. -4. The iOS app is running on a real iPhone, not the iOS simulator. -5. Push permissions were granted on the device. From 13919e5c4ac25ebe3be965482b5af04a19a6649e Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 12:09:25 -0700 Subject: [PATCH 07/18] scripts --- mobile/asa-go/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mobile/asa-go/package.json b/mobile/asa-go/package.json index 54ae5aecf0..c7ed858be1 100644 --- a/mobile/asa-go/package.json +++ b/mobile/asa-go/package.json @@ -12,12 +12,12 @@ "preview": "vite preview", "build:dev": "vite build --mode development", "build:prod": "vite build --mode production", - "cap:sync:dev": "APP_ENV=dev yarn build:dev && APP_ENV=dev yarn cap sync", - "cap:sync:prod": "APP_ENV=prod yarn build:prod && APP_ENV=prod yarn cap sync", - "cap:sync:android:dev": "APP_ENV=dev yarn build:dev && APP_ENV=dev yarn cap sync android", - "cap:sync:android:prod": "APP_ENV=prod yarn build:prod && APP_ENV=prod yarn cap sync android", - "cap:sync:ios:dev": "APP_ENV=dev yarn build:dev && APP_ENV=dev yarn cap sync ios", - "cap:sync:ios:prod": "APP_ENV=prod yarn build:prod && APP_ENV=prod yarn cap sync ios" + "cap:sync:dev": "yarn build:dev && APP_ENV=dev yarn cap sync", + "cap:sync:prod": "yarn build:prod && APP_ENV=prod yarn cap sync", + "cap:sync:android:dev": "yarn build:dev && APP_ENV=dev yarn cap sync android", + "cap:sync:android:prod": "yarn build:prod && APP_ENV=prod yarn cap sync android", + "cap:sync:ios:dev": "yarn build:dev && APP_ENV=dev yarn cap sync ios", + "cap:sync:ios:prod": "yarn build:prod && APP_ENV=prod yarn cap sync ios" }, "dependencies": { "@capacitor-firebase/messaging": "^8.1.0", From 59781e89ee7a8dc900b370e049a36cee047514ad Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 14:00:30 -0700 Subject: [PATCH 08/18] actions --- .github/workflows/asa_go_android_build.yml | 16 +++++++++++----- .github/workflows/asa_go_integration.yml | 8 ++++---- .github/workflows/asa_go_ios_build_deploy.yml | 11 ++++++++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/.github/workflows/asa_go_android_build.yml b/.github/workflows/asa_go_android_build.yml index 5fe0f0cb8f..e91fb9b110 100644 --- a/.github/workflows/asa_go_android_build.yml +++ b/.github/workflows/asa_go_android_build.yml @@ -20,6 +20,7 @@ jobs: "KEY_ALIAS" "SIGNING_STORE_PASSWORD" "SIGNING_KEY_PASSWORD" + "GOOGLE_SERVICES_JSON" "VITE_BASEMAP_TILE_URL" "VITE_BASEMAP_STYLE_URL" ) @@ -34,6 +35,7 @@ jobs: KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} SIGNING_STORE_PASSWORD: ${{ secrets.ANDROID_SIGNING_STORE_PASSWORD }} SIGNING_KEY_PASSWORD: ${{ secrets.ANDROID_SIGNING_KEY_PASSWORD }} + GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }} VITE_BASEMAP_TILE_URL: ${{ secrets.VITE_BASEMAP_TILE_URL }} VITE_BASEMAP_STYLE_URL: ${{ secrets.VITE_BASEMAP_STYLE_URL }} @@ -71,11 +73,15 @@ jobs: echo "VITE_BASEMAP_TILE_URL=${VITE_BASEMAP_TILE_URL}" >> .env.production echo "VITE_BASEMAP_STYLE_URL=${VITE_BASEMAP_STYLE_URL}" >> .env.production + - name: Create google-services.json + env: + GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }} + run: | + echo "$GOOGLE_SERVICES_JSON" | base64 -d > ./mobile/asa-go/android/app/src/prod/google-services.json + - name: Build Capacitor and Sync working-directory: ./mobile/asa-go - run: | - yarn build:prod - yarn cap sync android + run: yarn cap:sync:android:prod - name: Set up Java uses: actions/setup-java@v5 @@ -104,11 +110,11 @@ jobs: ANDROID_SIGNING_STORE_PASSWORD: ${{ secrets.ANDROID_SIGNING_STORE_PASSWORD }} ANDROID_SIGNING_KEY_PASSWORD: ${{ secrets.ANDROID_SIGNING_KEY_PASSWORD }} run: | - ./gradlew bundleRelease + ./gradlew bundleProdRelease - uses: actions/upload-artifact@v7 with: name: ASA-Go-AAB - path: mobile/asa-go/android/app/build/outputs/bundle/release/*.aab + path: mobile/asa-go/android/app/build/outputs/bundle/prodRelease/*.aab retention-days: 1 if-no-files-found: error diff --git a/.github/workflows/asa_go_integration.yml b/.github/workflows/asa_go_integration.yml index 016c9024df..5c686a0bc8 100644 --- a/.github/workflows/asa_go_integration.yml +++ b/.github/workflows/asa_go_integration.yml @@ -46,7 +46,7 @@ jobs: uses: ./.github/actions/asa-go-setup - name: Sync Capacitor iOS working-directory: ./mobile/asa-go - run: yarn cap sync ios + run: APP_ENV=prod yarn cap sync ios - name: Use Xcode latest stable uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd with: @@ -80,10 +80,10 @@ jobs: - name: Create google-services.json env: GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }} - run: echo "$GOOGLE_SERVICES_JSON" | base64 -d > ./mobile/asa-go/android/app/google-services.json + run: echo "$GOOGLE_SERVICES_JSON" | base64 -d > ./mobile/asa-go/android/app/src/prod/google-services.json - name: Sync Capacitor Android working-directory: ./mobile/asa-go - run: yarn cap sync android + run: APP_ENV=prod yarn cap sync android - name: Set up Java uses: actions/setup-java@v4 with: @@ -98,7 +98,7 @@ jobs: working-directory: ./mobile/keycloak/android run: ./gradlew jacocoTestReport - name: Upload Android coverage to Codecov - uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4 + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} files: | diff --git a/.github/workflows/asa_go_ios_build_deploy.yml b/.github/workflows/asa_go_ios_build_deploy.yml index ce8d4cddbb..2365ed6172 100644 --- a/.github/workflows/asa_go_ios_build_deploy.yml +++ b/.github/workflows/asa_go_ios_build_deploy.yml @@ -21,6 +21,7 @@ jobs: "CERTIFICATE" "KEYCHAIN_PASSWD" "PROVISIONING_PROFILE" + "GOOGLE_SERVICES_PLIST" "VITE_BASEMAP_TILE_URL" "VITE_BASEMAP_STYLE_URL" ) @@ -34,6 +35,7 @@ jobs: CERTIFICATE: ${{ secrets.APPLE_APP_STORE_BUILD_CERTIFICATE_BASE64 }} KEYCHAIN_PASSWD: ${{ secrets.APPLE_APP_STORE_BUILD_CERTIFICATE_PASSWD }} PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISION_PROFILE_BASE64 }} + GOOGLE_SERVICES_PLIST: ${{ secrets.GOOGLE_SERVICES_PLIST }} VITE_BASEMAP_TILE_URL: ${{ secrets.VITE_BASEMAP_TILE_URL }} VITE_BASEMAP_STYLE_URL: ${{ secrets.VITE_BASEMAP_STYLE_URL }} build-and-publish: @@ -69,11 +71,18 @@ jobs: echo "VITE_BASEMAP_TILE_URL=${VITE_BASEMAP_TILE_URL}" >>.env.production echo "VITE_BASEMAP_STYLE_URL=${VITE_BASEMAP_STYLE_URL}" >>.env.production + - name: Copy GoogleService-Info.plist + env: + GOOGLE_SERVICES_PLIST: ${{ secrets.GOOGLE_SERVICES_PLIST }} + working-directory: ./mobile/asa-go + run: | + echo "$GOOGLE_SERVICES_PLIST" | base64 --decode > ./ios/App/App/Firebase/Prod/GoogleService-Info.plist + - name: Build Capacitor and Sync working-directory: ./mobile/asa-go run: | yarn build:prod - yarn cap sync ios + APP_ENV=prod yarn cap sync ios - name: Setup iOS Signing env: BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_APP_STORE_BUILD_CERTIFICATE_BASE64 }} From 1be6637ef980f072d97ef46085890d35d7aaf457 Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 14:03:37 -0700 Subject: [PATCH 09/18] sha --- .github/workflows/asa_go_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/asa_go_integration.yml b/.github/workflows/asa_go_integration.yml index 5c686a0bc8..114ad83a8e 100644 --- a/.github/workflows/asa_go_integration.yml +++ b/.github/workflows/asa_go_integration.yml @@ -98,7 +98,7 @@ jobs: working-directory: ./mobile/keycloak/android run: ./gradlew jacocoTestReport - name: Upload Android coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4 with: token: ${{ secrets.CODECOV_TOKEN }} files: | From f8bf3cb8f786ecfacca76580860a009180518a4b Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 14:12:20 -0700 Subject: [PATCH 10/18] version bump --- .github/workflows/asa_go_android_build.yml | 2 +- .github/workflows/asa_go_ios_build_deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/asa_go_android_build.yml b/.github/workflows/asa_go_android_build.yml index e91fb9b110..056146a4d4 100644 --- a/.github/workflows/asa_go_android_build.yml +++ b/.github/workflows/asa_go_android_build.yml @@ -1,7 +1,7 @@ name: Build ASA Go Android env: - appBuildVersion: "1.0.2" + appBuildVersion: "1.0.3" on: workflow_dispatch: diff --git a/.github/workflows/asa_go_ios_build_deploy.yml b/.github/workflows/asa_go_ios_build_deploy.yml index 2365ed6172..f9f82b6e9f 100644 --- a/.github/workflows/asa_go_ios_build_deploy.yml +++ b/.github/workflows/asa_go_ios_build_deploy.yml @@ -2,7 +2,7 @@ name: Publish ASA Go iOS env: appBuildNumber: ${{ github.run_number }} - appBuildVersion: "1.0.2" + appBuildVersion: "1.0.3" permissions: contents: read From 3ab176d234ba28b3ebac752a7edd4be1e474ea19 Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 14:20:47 -0700 Subject: [PATCH 11/18] use script --- .github/workflows/asa_go_ios_build_deploy.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/asa_go_ios_build_deploy.yml b/.github/workflows/asa_go_ios_build_deploy.yml index f9f82b6e9f..25bb22794e 100644 --- a/.github/workflows/asa_go_ios_build_deploy.yml +++ b/.github/workflows/asa_go_ios_build_deploy.yml @@ -80,9 +80,7 @@ jobs: - name: Build Capacitor and Sync working-directory: ./mobile/asa-go - run: | - yarn build:prod - APP_ENV=prod yarn cap sync ios + run: yarn cap:sync:ios:prod - name: Setup iOS Signing env: BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_APP_STORE_BUILD_CERTIFICATE_BASE64 }} From 8942f642aaa91a8eaca9539a5d514e9792f89b23 Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 15:19:55 -0700 Subject: [PATCH 12/18] remove build from shared action --- .github/actions/asa-go-setup/action.yml | 5 ----- .github/workflows/asa_go_integration.yml | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/actions/asa-go-setup/action.yml b/.github/actions/asa-go-setup/action.yml index f0ac48e64a..f9093544bc 100644 --- a/.github/actions/asa-go-setup/action.yml +++ b/.github/actions/asa-go-setup/action.yml @@ -37,8 +37,3 @@ runs: working-directory: ./mobile/asa-go shell: bash run: yarn install - - - name: Build - working-directory: ./mobile/asa-go - shell: bash - run: yarn build diff --git a/.github/workflows/asa_go_integration.yml b/.github/workflows/asa_go_integration.yml index 114ad83a8e..69a48ea8b9 100644 --- a/.github/workflows/asa_go_integration.yml +++ b/.github/workflows/asa_go_integration.yml @@ -46,7 +46,7 @@ jobs: uses: ./.github/actions/asa-go-setup - name: Sync Capacitor iOS working-directory: ./mobile/asa-go - run: APP_ENV=prod yarn cap sync ios + run: yarn cap:sync:ios:prod - name: Use Xcode latest stable uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd with: @@ -83,7 +83,7 @@ jobs: run: echo "$GOOGLE_SERVICES_JSON" | base64 -d > ./mobile/asa-go/android/app/src/prod/google-services.json - name: Sync Capacitor Android working-directory: ./mobile/asa-go - run: APP_ENV=prod yarn cap sync android + run: yarn cap:sync:android:prod - name: Set up Java uses: actions/setup-java@v4 with: From 0a8859b3b667af3a8a2a5008e8265eff063ecd6e Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 16:11:24 -0700 Subject: [PATCH 13/18] build readme --- mobile/asa-go/README.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/mobile/asa-go/README.md b/mobile/asa-go/README.md index 67c529c5e1..77694eb467 100644 --- a/mobile/asa-go/README.md +++ b/mobile/asa-go/README.md @@ -86,9 +86,24 @@ pmtiles extract https://build.protomaps.com/20250326.pmtiles bc_basemap_20250326 ### Distributing -Bump `appBuildVersion` appropriately via semvar, in `.github/workflows/asa_go_build_deploy.yml`. -Run: `gh workflow run "Publish ASA Go"` -This will build and publish the app that is on the `main` branch. +Bump `appBuildVersion` appropriately in: + +- `.github/workflows/asa_go_android_build.yml` +- `.github/workflows/asa_go_ios_build_deploy.yml` + +Run the Android build workflow: + +```bash +gh workflow run "Build ASA Go Android" --ref +``` + +Run the iOS build/deploy workflow: + +```bash +gh workflow run "Publish ASA Go iOS" --ref +``` + +These workflows build the app from the specified branch. ## CI Workflows @@ -104,7 +119,7 @@ All three jobs use the shared composite action `.github/actions/asa-go-setup`, w 1. Sets up Node.js 20 2. Caches and installs `mobile/keycloak` node_modules, then runs `yarn build` -3. Caches and installs `mobile/asa-go` node_modules, then runs `yarn build` +3. Caches and installs `mobile/asa-go` node_modules ### Android Release Build (`.github/workflows/asa_go_android_build.yml`) From 4f0c64d36067c46a83d3b14f236b964c38263dfd Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 16:19:12 -0700 Subject: [PATCH 14/18] google play fingerprint --- mobile/asa-go/Notifications.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mobile/asa-go/Notifications.md b/mobile/asa-go/Notifications.md index 2cda08938a..80d92631bc 100644 --- a/mobile/asa-go/Notifications.md +++ b/mobile/asa-go/Notifications.md @@ -66,6 +66,11 @@ It tells the Android app which Firebase project/app to talk to, including: It is required locally in the Android project. +## Google Play App Signing + +When distributing via the Play Store, Google re-signs your APK with their own App Signing Key rather than your local upload key. Firebase needs the SHA-1 of this key registered to validate the app's identity when requesting FCM tokens. +To get it: Play Console -> Test and release -> App Integrity -> App signing → copy the SHA-1 and add it to the app in Firebase Console under Project Settings. + ## APNs auth key The APNs auth key is the Apple push key used by Firebase to send iOS notifications through APNs. From e8869c4647d64d69c9b9344d6b2a6463f99ab86d Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Tue, 17 Mar 2026 16:24:03 -0700 Subject: [PATCH 15/18] readme change --- mobile/asa-go/Notifications.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mobile/asa-go/Notifications.md b/mobile/asa-go/Notifications.md index 80d92631bc..89fa492e9c 100644 --- a/mobile/asa-go/Notifications.md +++ b/mobile/asa-go/Notifications.md @@ -77,9 +77,7 @@ The APNs auth key is the Apple push key used by Firebase to send iOS notificatio Important points: -- It does not go in this repo. -- It does not go in Xcode project files. -- It is uploaded in Firebase Console. +- It is only uploaded in Firebase Console. - It can be used for both development and production APNs delivery. Because we have separate Firebase setups for dev and prod, make sure the Firebase project used by each app has APNs configured. From aaeb387d1d60a5065e76a099a05ab75a7d7bb711 Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Wed, 18 Mar 2026 10:10:33 -0700 Subject: [PATCH 16/18] minor readme change --- mobile/asa-go/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/asa-go/README.md b/mobile/asa-go/README.md index 77694eb467..1dfdf6752a 100644 --- a/mobile/asa-go/README.md +++ b/mobile/asa-go/README.md @@ -2,7 +2,7 @@ Capacitor app using react/vite. -For iOS/Firebase push notification setup details, see [Notifications.md](Notifications.md). +For iOS & Android Firebase push notification setup details, see [Notifications.md](Notifications.md). ## Building From c733f52cee0d00225acc2887fc267b829edd262a Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Wed, 18 Mar 2026 10:23:41 -0700 Subject: [PATCH 17/18] Update mobile/asa-go/Notifications.md Co-authored-by: Conor Brady --- mobile/asa-go/Notifications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/asa-go/Notifications.md b/mobile/asa-go/Notifications.md index 89fa492e9c..60ab0875e7 100644 --- a/mobile/asa-go/Notifications.md +++ b/mobile/asa-go/Notifications.md @@ -84,7 +84,7 @@ Because we have separate Firebase setups for dev and prod, make sure the Firebas ## What lives where -In the app repo: +In the app folder: - iOS bundle IDs - Android application IDs / flavors From 3a0db128027a4d3f3e920068614e5a6959896846 Mon Sep 17 00:00:00 2001 From: Brett Edwards Date: Wed, 18 Mar 2026 10:43:42 -0700 Subject: [PATCH 18/18] notifications.md tweak --- mobile/asa-go/Notifications.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mobile/asa-go/Notifications.md b/mobile/asa-go/Notifications.md index 60ab0875e7..67db29f6b0 100644 --- a/mobile/asa-go/Notifications.md +++ b/mobile/asa-go/Notifications.md @@ -22,13 +22,6 @@ These application IDs must match the Firebase Android app registration exactly. ## Firebase dev vs prod -We use different Firebase app configs for prod and dev on both platforms. - -- Prod Firebase plist: `ios/App/App/Firebase/Prod/GoogleService-Info.plist` -- Dev Firebase plist: `ios/App/App/Firebase/Dev/GoogleService-Info.plist` -- Prod Android config: `android/app/src/prod/google-services.json` -- Dev Android config: `android/app/src/dev/google-services.json` - Current mapping: - Prod plist `BUNDLE_ID`: `ca.bc.gov.asago` @@ -84,6 +77,13 @@ Because we have separate Firebase setups for dev and prod, make sure the Firebas ## What lives where +We use different Firebase app configs for prod and dev on both platforms. + +- Prod Firebase plist: `ios/App/App/Firebase/Prod/GoogleService-Info.plist` +- Dev Firebase plist: `ios/App/App/Firebase/Dev/GoogleService-Info.plist` +- Prod Android config: `android/app/src/prod/google-services.json` +- Dev Android config: `android/app/src/dev/google-services.json` + In the app folder: - iOS bundle IDs @@ -95,9 +95,9 @@ In the app folder: In Firebase Console: -- APNs auth key upload +- APNs auth key upload for iOS +- Android SHA-1 upload for Android - Firebase app registration for each bundle ID -- Cloud Messaging setup ## Why we use separate app IDs