Skip to content

Make FirebaseAnalytics available for watchOS, which build runtime error #9966

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gpfister opened this issue Jun 30, 2022 · 10 comments
Closed

Comments

@gpfister
Copy link

Feature proposal

  • Firebase Component: Analytics

A bit of context first: I have create a Swift Package for my app for all my cloud API, so that it can be shared among apps (macOS, iOS, watchOS, tvOS). Though SPM offers the possibility to make a target dependency conditional to the platform, this condition is only checked after the dependency has been resolved for this platform, which pose a problem for FirebaseAnalytics, has there's no watchOS build. So when configuring my package, I end up with a build error, though for the target I have a condition the dependency to FirebaseAnalytics only for iOS and macOS.

My request is the following one: instead of not providing Firebase Analytics for watchOS, make it available, but add an error at build time when the OS is watchOS:

#if os(watchOS)
    #error FirebaseAnalytics is not supported for watchOS <some ref to the page where we can see which API is supported on which platform>
#endif

Typically FirebaseFirestore does the same. When building on watchOS, it gives an error (which is not actually perfect) about storage not been clearly identified on watchOS.

That way, we can still build a single API, even if for certain OS the FirebaseAnalytics API is ignored, until a day where it becomes available for watchOS (if it ever make sense, probably not).

Note: This feature request could be extended to all API for each of their unsupported platform. Please not that for each of these API, if they depend on other API, conditions should be added, as SPM resolve each dependency dependencies as well, before considering conditions.

@google-oss-bot
Copy link

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

@charlotteliang
Copy link
Contributor

charlotteliang commented Jul 6, 2022

@gpfister Thank you for filling the request, can you share with me your Package.swift file setup? You can obscure the part unrelated to Firebase or you can send directly to my email at chliang at google.com

@gpfister
Copy link
Author

gpfister commented Jul 8, 2022

@chliangGoogle Sure, here's an example:

import PackageDescription

let package = Package(
    name: "MyCloudKit",
    platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v8)],
    products: [
        .library(
            name: "MyCloudAnalytics",
            targets: ["MyCloudAnalytics"]
        ),
        .library(
            name: "MyCloudAuth",
            targets: ["MyCloudAuth"]
        ),
        .library(
            name: "MyCloudCore",
            targets: ["MyCloudCore"]
        ),
        .library(
            name: "MyCloudModel",
            targets: ["MyCloudModel"]
        ),
        .library(
            name: "MyCloudServices",
            targets: ["MyCloudServices"]
        )
    ],
    dependencies: [
        .package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "9.2.0")),
    ],
    targets: [
        .target(
            name: "MyCloudAnalytics",
            dependencies: [
                .product(name: "FirebaseAnalytics", package: "firebase-ios-sdk"),
                .product(name: "FirebaseCrashlytics", package: "firebase-ios-sdk"),
            ]
        ),
        .target(
            name: "MyCloudAuth",
            dependencies: [
                .target(name: "OSKCloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
                .target(name: "OSKCloudModel"),
                .product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
            ]
        ),
        .target(
            name: "MyCloudCore",
            dependencies: [
                .product(name: "FirebaseAppCheck", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
                .product(name: "FirebaseFirestore", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
                .product(name: "FirebaseStorage", package: "firebase-ios-sdk")
            ]
        ),
        .target(
            name: "MyCloudModel",
            dependencies: [
                .product(name: "FirebaseFirestoreSwift", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
            ]
        ),
        .target(
            name: "MyCloudServices",
            dependencies: [
                .target(name: "MyCloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
                .target(name: "MyCloudModel"),
                .product(name: "FirebaseAnalytics", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseFirestore", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
                .product(name: "FirebaseStorage", package: "firebase-ios-sdk")
            ]
        ),
    ]
)

The MyCloudAuth is the one that you can use as example: the idea would be that on iOS there would be some analytics, and on watchOS there would be only the FirebaseAuth.

For reference, I have open an issue on Apple/Swift repo. However, while it should very likely be fixed there (I don't understand why it tries to eval the dependency, though it doesn't meet the conditions), the solution I'm proposing here is more like to be added in a timely manner.

Thank in advance for your support.

@charlotteliang
Copy link
Contributor

@gpfister You mean Firestore works as expected right: It will let you build with an error, which is not like Analytics.

@gpfister
Copy link
Author

@chliangGoogle Yes. It seems that before considering the condition, SPM will check if the dependency is available for the arch you are building for. So in the example: FirebaseFirestore is ignored properly (if the conditions was removed, it would try to build it for warchOS, but an error is raised regarding local storage), however for FirebaseAnalytics, it fails even with the conditions, as there is no FirebaseAnalytics for watchOS arch.

@charlotteliang
Copy link
Contributor

@gpfister We took a close look at and realize we are not able to provide a walk-around in our infrastructure at the moment. We will closely monitor the issue in Apple/Swift repo and thank you for filing it. Please upvote if anyone runs into the same issue.

@ben-p-commits
Copy link

@chliangGoogle - @gpfister has responded to the issue, and has a suggestion for firebase to workaround

Thoughts?

@paulb777
Copy link
Member

Xcode 14.3 has this release note:

Fixed: Conditional target dependencies ([SE-0273](https://github.com/apple/swift-evolution/blob/main/proposals/0273-swiftpm-conditional-target-dependencies.md)) in packages are now correctly applied to binary targets and leads to top-level targets being filtered out from builds of root packages. (85762201)

Does it address this issue?

@gpfister
Copy link
Author

gpfister commented Mar 2, 2023

@paulb777, sorry for getting back to you a bit late. I did some testing after using conditions in target dependencies and I was able to build the code using Xcode 14.3 (Version 14.3 beta 2 (14E5207e)). It looks like this is going to be solved.

Shall I close the issue or wait the final release of Xcode 14.3.

For those that are interested, here's how it looks like:

// swift-tools-version:5.7

import PackageDescription

let package = Package(
    name: "CloudKit",
    platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v8)],
    products: [
        .library(
            name: "CloudAnalytics",
            targets: ["CloudAnalytics"]
        ),
        .library(
            name: "CloudAuth",
            targets: ["CloudAuth"]
        ),
        .library(
            name: "CloudCore",
            targets: ["CloudCore"]
        ),
        .library(
            name: "CloudModel",
            targets: ["CloudModel"]
        ),
        .library(
            name: "CloudServices",
            targets: ["CloudServices"]
        ),
    ],
    dependencies: [
        .package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "10.2.0")),
    ],
    targets: [
        .target(
            name: "CloudAnalytics",
            dependencies: [
                .product(name: "FirebaseAnalytics", package: "firebase-ios-sdk"),
                .product(name: "FirebaseCrashlytics", package: "firebase-ios-sdk"),
            ]
        ),
        .target(
            name: "CloudAuth",
            dependencies: [
                .target(name: "CloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
                .target(name: "CloudModel"),
                .product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
            ]
        ),
        .target(
            name: "CloudCore",
            dependencies: [
                .product(name: "FirebaseAppCheck", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
                .product(name: "FirebaseFirestore", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseFunctions", package: "firebase-ios-sdk"),
                .product(name: "FirebaseStorage", package: "firebase-ios-sdk"),
            ]
        ),
        .target(
            name: "CloudModel",
            dependencies: [
                .product(name: "FirebaseFirestoreSwift", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
            ]
        ),
        .target(
            name: "CloudServices",
            dependencies: [
                .target(name: "CloudAnalytics", condition: .when(platforms: [.iOS, .macOS])),
                .target(name: "CloudModel"),
                .product(name: "FirebaseAnalytics", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseFirestore", package: "firebase-ios-sdk"),
                .product(name: "FirebaseFunctions", package: "firebase-ios-sdk", condition: .when(platforms: [.iOS, .macOS])),
                .product(name: "FirebaseStorage", package: "firebase-ios-sdk"),
            ]
        ),
        .testTarget(
            name: "CloudKitTests",
            dependencies: [
                "CloudModel",
                "CloudServices",
            ]
        ),
    ]
)

@paulb777
Copy link
Member

paulb777 commented Mar 2, 2023

Thanks for sharing @gpfister! I'll close with the note to update to at least Xcode 14.3

@paulb777 paulb777 closed this as completed Mar 2, 2023
@firebase firebase locked and limited conversation to collaborators Apr 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants