From 3a36f1e212176d7bbfe564e8dde7ae1bd398cf43 Mon Sep 17 00:00:00 2001 From: Mikaela Caron Date: Thu, 10 Oct 2024 04:53:12 +0100 Subject: [PATCH 1/5] Remove deprecated libraries and update Firebase --- .../project.pbxproj | 26 +------------------ .../xcshareddata/swiftpm/Package.resolved | 24 ++++++++--------- .../ViewModels/DashboardViewModel.swift | 1 - .../ViewModels/MainTabViewModel.swift | 1 - .../Shared/Models/AlertItem.swift | 2 +- .../Shared/Models/MaintenanceEvent.swift | 2 +- .../Shared/Models/OdometerReading.swift | 2 +- .../Shared/Models/Vehicle.swift | 2 +- .../ViewModels/OdometerViewModel.swift | 1 - .../ViewModels/SettingsViewModel.swift | 1 - .../FirebaseAnalytics+Extension.swift | 2 +- 11 files changed, 18 insertions(+), 46 deletions(-) diff --git a/Basic-Car-Maintenance.xcodeproj/project.pbxproj b/Basic-Car-Maintenance.xcodeproj/project.pbxproj index 4a4be555..6ef80096 100644 --- a/Basic-Car-Maintenance.xcodeproj/project.pbxproj +++ b/Basic-Car-Maintenance.xcodeproj/project.pbxproj @@ -9,13 +9,10 @@ /* Begin PBXBuildFile section */ FF153AFF2B07C3E000D0BA30 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = FF153AFE2B07C3E000D0BA30 /* FirebaseCrashlytics */; }; FF4E82BE2AD39863004949AF /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = FF4E82BD2AD39863004949AF /* FirebaseRemoteConfig */; }; - FF4E82C02AD39863004949AF /* FirebaseRemoteConfigSwift in Frameworks */ = {isa = PBXBuildFile; productRef = FF4E82BF2AD39863004949AF /* FirebaseRemoteConfigSwift */; }; FF4E82C22AD39863004949AF /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = FF4E82C12AD39863004949AF /* FirebaseStorage */; }; FFC8CDA72AA3867A00D129A6 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = FFC8CDA62AA3867A00D129A6 /* FirebaseAnalytics */; }; - FFC8CDA92AA3867A00D129A6 /* FirebaseAnalyticsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = FFC8CDA82AA3867A00D129A6 /* FirebaseAnalyticsSwift */; }; FFC8CDAB2AA3867A00D129A6 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = FFC8CDAA2AA3867A00D129A6 /* FirebaseAuth */; }; FFC8CDAD2AA3867A00D129A6 /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = FFC8CDAC2AA3867A00D129A6 /* FirebaseFirestore */; }; - FFC8CDAF2AA3867A00D129A6 /* FirebaseFirestoreSwift in Frameworks */ = {isa = PBXBuildFile; productRef = FFC8CDAE2AA3867A00D129A6 /* FirebaseFirestoreSwift */; }; FFC8CDB32AA4226900D129A6 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FFC8CDB22AA4226900D129A6 /* AdSupport.framework */; }; FFDADF7F2ACD35A100DDEF79 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FFDADF7E2ACD35A100DDEF79 /* WidgetKit.framework */; }; FFDADF812ACD35A100DDEF79 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FFDADF802ACD35A100DDEF79 /* SwiftUI.framework */; }; @@ -104,12 +101,9 @@ buildActionMask = 2147483647; files = ( FF4E82BE2AD39863004949AF /* FirebaseRemoteConfig in Frameworks */, - FFC8CDAF2AA3867A00D129A6 /* FirebaseFirestoreSwift in Frameworks */, - FFC8CDA92AA3867A00D129A6 /* FirebaseAnalyticsSwift in Frameworks */, FFC8CDAD2AA3867A00D129A6 /* FirebaseFirestore in Frameworks */, FFC8CDAB2AA3867A00D129A6 /* FirebaseAuth in Frameworks */, FFC8CDA72AA3867A00D129A6 /* FirebaseAnalytics in Frameworks */, - FF4E82C02AD39863004949AF /* FirebaseRemoteConfigSwift in Frameworks */, FF153AFF2B07C3E000D0BA30 /* FirebaseCrashlytics in Frameworks */, FF4E82C22AD39863004949AF /* FirebaseStorage in Frameworks */, FFC8CDB32AA4226900D129A6 /* AdSupport.framework in Frameworks */, @@ -203,12 +197,9 @@ name = "Basic-Car-Maintenance"; packageProductDependencies = ( FFC8CDA62AA3867A00D129A6 /* FirebaseAnalytics */, - FFC8CDA82AA3867A00D129A6 /* FirebaseAnalyticsSwift */, FFC8CDAA2AA3867A00D129A6 /* FirebaseAuth */, FFC8CDAC2AA3867A00D129A6 /* FirebaseFirestore */, - FFC8CDAE2AA3867A00D129A6 /* FirebaseFirestoreSwift */, FF4E82BD2AD39863004949AF /* FirebaseRemoteConfig */, - FF4E82BF2AD39863004949AF /* FirebaseRemoteConfigSwift */, FF4E82C12AD39863004949AF /* FirebaseStorage */, FF153AFE2B07C3E000D0BA30 /* FirebaseCrashlytics */, ); @@ -856,7 +847,7 @@ repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 10.14.0; + minimumVersion = 11.0.0; }; }; /* End XCRemoteSwiftPackageReference section */ @@ -877,11 +868,6 @@ package = FFC8CDA52AA3867A00D129A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseRemoteConfig; }; - FF4E82BF2AD39863004949AF /* FirebaseRemoteConfigSwift */ = { - isa = XCSwiftPackageProductDependency; - package = FFC8CDA52AA3867A00D129A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseRemoteConfigSwift; - }; FF4E82C12AD39863004949AF /* FirebaseStorage */ = { isa = XCSwiftPackageProductDependency; package = FFC8CDA52AA3867A00D129A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; @@ -892,11 +878,6 @@ package = FFC8CDA52AA3867A00D129A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseAnalytics; }; - FFC8CDA82AA3867A00D129A6 /* FirebaseAnalyticsSwift */ = { - isa = XCSwiftPackageProductDependency; - package = FFC8CDA52AA3867A00D129A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAnalyticsSwift; - }; FFC8CDAA2AA3867A00D129A6 /* FirebaseAuth */ = { isa = XCSwiftPackageProductDependency; package = FFC8CDA52AA3867A00D129A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; @@ -907,11 +888,6 @@ package = FFC8CDA52AA3867A00D129A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseFirestore; }; - FFC8CDAE2AA3867A00D129A6 /* FirebaseFirestoreSwift */ = { - isa = XCSwiftPackageProductDependency; - package = FFC8CDA52AA3867A00D129A6 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseFirestoreSwift; - }; /* End XCSwiftPackageProductDependency section */ }; rootObject = FF5D139B2A86C2D500BC9BD6 /* Project object */; diff --git a/Basic-Car-Maintenance.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Basic-Car-Maintenance.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 51752bbf..3e151548 100644 --- a/Basic-Car-Maintenance.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Basic-Car-Maintenance.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,8 +15,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/app-check.git", "state" : { - "revision" : "3b62f154d00019ae29a71e9738800bb6f18b236d", - "version" : "10.19.2" + "revision" : "87dd288fc792bf9751e522e171a47df5b783b0b8", + "version" : "11.1.0" } }, { @@ -24,8 +24,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk.git", "state" : { - "revision" : "eca84fd638116dd6adb633b5a3f31cc7befcbb7d", - "version" : "10.29.0" + "revision" : "f909f901bfba9e27e4e9da83242a4915d6dd64bb", + "version" : "11.3.0" } }, { @@ -33,8 +33,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { - "revision" : "fe727587518729046fc1465625b9afd80b5ab361", - "version" : "10.28.0" + "revision" : "93406fd21b85e66e2d6dbf50b472161fd75c3f1f", + "version" : "11.3.0" } }, { @@ -42,8 +42,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleDataTransport.git", "state" : { - "revision" : "a637d318ae7ae246b02d7305121275bc75ed5565", - "version" : "9.4.0" + "revision" : "617af071af9aa1d6a091d59a202910ac482128f9", + "version" : "10.1.0" } }, { @@ -51,8 +51,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleUtilities.git", "state" : { - "revision" : "57a1d307f42df690fdef2637f3e5b776da02aad6", - "version" : "7.13.3" + "revision" : "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb", + "version" : "8.0.2" } }, { @@ -60,8 +60,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/grpc-binary.git", "state" : { - "revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359", - "version" : "1.62.2" + "revision" : "f56d8fc3162de9a498377c7b6cea43431f4f5083", + "version" : "1.65.1" } }, { diff --git a/Basic-Car-Maintenance/Shared/Dashboard/ViewModels/DashboardViewModel.swift b/Basic-Car-Maintenance/Shared/Dashboard/ViewModels/DashboardViewModel.swift index c49ba813..f0dc8adf 100644 --- a/Basic-Car-Maintenance/Shared/Dashboard/ViewModels/DashboardViewModel.swift +++ b/Basic-Car-Maintenance/Shared/Dashboard/ViewModels/DashboardViewModel.swift @@ -7,7 +7,6 @@ // import FirebaseFirestore -import FirebaseFirestoreSwift import Foundation @Observable diff --git a/Basic-Car-Maintenance/Shared/MainView/ViewModels/MainTabViewModel.swift b/Basic-Car-Maintenance/Shared/MainView/ViewModels/MainTabViewModel.swift index ddb75d59..b2729d70 100644 --- a/Basic-Car-Maintenance/Shared/MainView/ViewModels/MainTabViewModel.swift +++ b/Basic-Car-Maintenance/Shared/MainView/ViewModels/MainTabViewModel.swift @@ -8,7 +8,6 @@ import Foundation import FirebaseFirestore -import FirebaseFirestoreSwift @Observable class MainTabViewModel { diff --git a/Basic-Car-Maintenance/Shared/Models/AlertItem.swift b/Basic-Car-Maintenance/Shared/Models/AlertItem.swift index 0b91b2e5..4bdfeb8e 100644 --- a/Basic-Car-Maintenance/Shared/Models/AlertItem.swift +++ b/Basic-Car-Maintenance/Shared/Models/AlertItem.swift @@ -7,7 +7,7 @@ // import Foundation -import FirebaseFirestoreSwift +import FirebaseFirestore import SwiftData struct AlertItem: Codable, Identifiable { diff --git a/Basic-Car-Maintenance/Shared/Models/MaintenanceEvent.swift b/Basic-Car-Maintenance/Shared/Models/MaintenanceEvent.swift index a6378951..18daa147 100644 --- a/Basic-Car-Maintenance/Shared/Models/MaintenanceEvent.swift +++ b/Basic-Car-Maintenance/Shared/Models/MaintenanceEvent.swift @@ -6,7 +6,7 @@ // See LICENSE for license information. // -import FirebaseFirestoreSwift +import FirebaseFirestore import Foundation struct MaintenanceEvent: Codable, Identifiable, Hashable { diff --git a/Basic-Car-Maintenance/Shared/Models/OdometerReading.swift b/Basic-Car-Maintenance/Shared/Models/OdometerReading.swift index 6c40926b..4595876e 100644 --- a/Basic-Car-Maintenance/Shared/Models/OdometerReading.swift +++ b/Basic-Car-Maintenance/Shared/Models/OdometerReading.swift @@ -7,7 +7,7 @@ // import Foundation -import FirebaseFirestoreSwift +import FirebaseFirestore struct OdometerReading: Codable, Identifiable, Hashable { @DocumentID var id: String? diff --git a/Basic-Car-Maintenance/Shared/Models/Vehicle.swift b/Basic-Car-Maintenance/Shared/Models/Vehicle.swift index 0b80d06a..b30b5bd9 100644 --- a/Basic-Car-Maintenance/Shared/Models/Vehicle.swift +++ b/Basic-Car-Maintenance/Shared/Models/Vehicle.swift @@ -6,7 +6,7 @@ // See LICENSE for license information. // -import FirebaseFirestoreSwift +import FirebaseFirestore import Foundation struct Vehicle: Codable, Identifiable, Hashable { diff --git a/Basic-Car-Maintenance/Shared/Odometer/ViewModels/OdometerViewModel.swift b/Basic-Car-Maintenance/Shared/Odometer/ViewModels/OdometerViewModel.swift index f56d1c81..ffc18260 100644 --- a/Basic-Car-Maintenance/Shared/Odometer/ViewModels/OdometerViewModel.swift +++ b/Basic-Car-Maintenance/Shared/Odometer/ViewModels/OdometerViewModel.swift @@ -7,7 +7,6 @@ // import FirebaseFirestore -import FirebaseFirestoreSwift import Foundation @Observable diff --git a/Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift b/Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift index 2e0af72e..cc1b423c 100644 --- a/Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift +++ b/Basic-Car-Maintenance/Shared/Settings/ViewModels/SettingsViewModel.swift @@ -7,7 +7,6 @@ // import FirebaseFirestore -import FirebaseFirestoreSwift import Foundation @Observable diff --git a/Basic-Car-Maintenance/Shared/Utilities/FirebaseAnalytics+Extension.swift b/Basic-Car-Maintenance/Shared/Utilities/FirebaseAnalytics+Extension.swift index 38b47a89..f80406d1 100644 --- a/Basic-Car-Maintenance/Shared/Utilities/FirebaseAnalytics+Extension.swift +++ b/Basic-Car-Maintenance/Shared/Utilities/FirebaseAnalytics+Extension.swift @@ -7,7 +7,7 @@ // import SwiftUI -import FirebaseAnalyticsSwift +import FirebaseAnalytics struct FirebaseAnalyticsModifier: ViewModifier { From 98d962b03383d5abb3e7b2f89ea89db99d2b2b51 Mon Sep 17 00:00:00 2001 From: Mikaela Caron Date: Thu, 10 Oct 2024 04:53:58 +0100 Subject: [PATCH 2/5] Update Firestore rules for emulator --- backend/firestore.rules | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/backend/firestore.rules b/backend/firestore.rules index 50713dba..ec4139d1 100644 --- a/backend/firestore.rules +++ b/backend/firestore.rules @@ -3,17 +3,13 @@ rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { - // This rule allows anyone with your Firestore database reference to view, edit, - // and delete all data in your Firestore database. It is useful for getting - // started, but it is configured to expire after 30 days because it - // leaves your app open to attackers. At that time, all client - // requests to your Firestore database will be denied. - // - // Make sure to write security rules for your app before that time, or else - // all client requests to your Firestore database will be denied until you Update - // your rules - match /{document=**} { - allow read, write: if true; + match /alerts/{document=**} { + allow read; + } + + match /vehicles/{vehicleId}/{document=**} { + allow read: if request.auth != null && request.auth.uid == resource.data.userID; + allow write: if request.auth != null && request.auth.uid == request.resource.data.userID; } } } \ No newline at end of file From 231db2b6adc1d81c9ff658704afa14cb504091a9 Mon Sep 17 00:00:00 2001 From: Mikaela Caron Date: Thu, 10 Oct 2024 04:55:41 +0100 Subject: [PATCH 3/5] Update Firestore rules in doc --- .../FirestoreCollections.md | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/Basic-Car-Maintenance/Documentation.docc/FirestoreCollections.md b/Basic-Car-Maintenance/Documentation.docc/FirestoreCollections.md index 6401104f..73aa0128 100644 --- a/Basic-Car-Maintenance/Documentation.docc/FirestoreCollections.md +++ b/Basic-Car-Maintenance/Documentation.docc/FirestoreCollections.md @@ -53,27 +53,22 @@ The vehicles collection contains all the vehicles associated with a specific use **alerts** : read-only for all users -**maintenance_events** : Authorized users can read and write to the maintenance events collection that is associated with their `userID`. - -**vehicles**: Authorized users can ready and write to vehicles collection that is associated with their `userID`. +**vehicles**: Authorized users can ready and write to vehicles collection that is associated with their `userID`. With `rules_version` set to `2`, the subcollections (`maintenance_events` and `odometer_readings`) will automatically have the same rules ``` -rules_version = '1'; -service cloud.firestore { -match /databases/{database}/documents { +rules_version = '2'; - match /alerts/{document=\*\*} { - allow read; - } +service cloud.firestore { + match /databases/{database}/documents { - match /maintenance_events/{allPaths=**} { - allow read, write: if request.auth != null && request.auth.uid == userId; + match /alerts/{document=**} { + allow read; } - match /vehicles/{allPaths=**} { - allow read, write: if request.auth != null && request.auth.uid == userId; - } + match /vehicles/{vehicleId}/{document=**} { + allow read: if request.auth != null && request.auth.uid == resource.data.userID; + allow write: if request.auth != null && request.auth.uid == request.resource.data.userID; } - + } } ``` From a87c22ee9329731429d8c11b7ffcd312162832c4 Mon Sep 17 00:00:00 2001 From: Mikaela Caron Date: Tue, 22 Oct 2024 05:19:49 -0400 Subject: [PATCH 4/5] Update Firebase --- .../xcshareddata/swiftpm/Package.resolved | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Basic-Car-Maintenance.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Basic-Car-Maintenance.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3e151548..bf72ba19 100644 --- a/Basic-Car-Maintenance.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Basic-Car-Maintenance.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,8 +15,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/app-check.git", "state" : { - "revision" : "87dd288fc792bf9751e522e171a47df5b783b0b8", - "version" : "11.1.0" + "revision" : "61b85103a1aeed8218f17c794687781505fbbef5", + "version" : "11.2.0" } }, { @@ -24,8 +24,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk.git", "state" : { - "revision" : "f909f901bfba9e27e4e9da83242a4915d6dd64bb", - "version" : "11.3.0" + "revision" : "8328630971a8fdd8072b36bb22bef732eb15e1f0", + "version" : "11.4.0" } }, { @@ -33,8 +33,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { - "revision" : "93406fd21b85e66e2d6dbf50b472161fd75c3f1f", - "version" : "11.3.0" + "revision" : "4f234bcbdae841d7015258fbbf8e7743a39b8200", + "version" : "11.4.0" } }, { @@ -69,8 +69,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/gtm-session-fetcher.git", "state" : { - "revision" : "a2ab612cb980066ee56d90d60d8462992c07f24b", - "version" : "3.5.0" + "revision" : "5cfe5f090c982de9c58605d2a82a4fc77b774fbd", + "version" : "4.1.0" } }, { @@ -114,8 +114,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-protobuf.git", "state" : { - "revision" : "edb6ed4919f7756157fe02f2552b7e3850a538e5", - "version" : "1.28.1" + "revision" : "ebc7251dd5b37f627c93698e4374084d98409633", + "version" : "1.28.2" } }, { From d9294ffe2a62f3739700f08eddf3375a89ac8f9a Mon Sep 17 00:00:00 2001 From: Mikaela Caron Date: Tue, 22 Oct 2024 06:33:20 -0400 Subject: [PATCH 5/5] add rules to docs, but use open rules for emulator --- .../Documentation.docc/FirestoreCollections.md | 10 +++++++--- backend/firestore.rules | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Basic-Car-Maintenance/Documentation.docc/FirestoreCollections.md b/Basic-Car-Maintenance/Documentation.docc/FirestoreCollections.md index 73aa0128..1aa692bb 100644 --- a/Basic-Car-Maintenance/Documentation.docc/FirestoreCollections.md +++ b/Basic-Car-Maintenance/Documentation.docc/FirestoreCollections.md @@ -53,7 +53,10 @@ The vehicles collection contains all the vehicles associated with a specific use **alerts** : read-only for all users -**vehicles**: Authorized users can ready and write to vehicles collection that is associated with their `userID`. With `rules_version` set to `2`, the subcollections (`maintenance_events` and `odometer_readings`) will automatically have the same rules +**vehicles**: Authorized users can ready and write to vehicles collection that is associated with their `userID`. With `rules_version` set to `2`, the subcollections (`maintenance_events` and `odometer_readings`) will automatically have the same rules + +> At the moment this is recommended, but not in production yet, because this is failing in the emulator + ``` rules_version = '2'; @@ -66,8 +69,9 @@ service cloud.firestore { } match /vehicles/{vehicleId}/{document=**} { - allow read: if request.auth != null && request.auth.uid == resource.data.userID; - allow write: if request.auth != null && request.auth.uid == request.resource.data.userID; + // Allow users to create vehicles if authenticated + allow create: if request.auth != null; + allow read, update, delete: if request.auth != null && resource.data.userID == request.auth.uid; } } } diff --git a/backend/firestore.rules b/backend/firestore.rules index ec4139d1..68841121 100644 --- a/backend/firestore.rules +++ b/backend/firestore.rules @@ -8,8 +8,8 @@ service cloud.firestore { } match /vehicles/{vehicleId}/{document=**} { - allow read: if request.auth != null && request.auth.uid == resource.data.userID; - allow write: if request.auth != null && request.auth.uid == request.resource.data.userID; + // Allow users to create vehicles if authenticated + allow read, write: if true; } } } \ No newline at end of file