firebase / firebase-unity-sdk

The Firebase SDK for Unity
http://firebase.google.com
Apache License 2.0
216 stars 35 forks source link

[Bug] Incremental firebase Unity-iOS builds reset code signing on gRPC-Certificates #644

Closed ferretnt closed 5 months ago

ferretnt commented 1 year ago

[REQUIRED] Please fill in the following fields:

[REQUIRED] Please describe the issue here:

Iterating on iOS Unity builds of firebase projects seems to have regressed over the last couple of years, in that.

Specifically:

It would be great if incremental builds of Firebase could have their painless iteration restored (it's been a while since I was working on a Firebase project, but from memory Firebase 7.x didn't have these issues?)

Steps to reproduce:

(a) Create a firebase project with the above components. Fix signing, bitcode, etc errors whilst building in latest XCode (14.2 at time of writing) (B) Build and Run on device. (c) Incrementally build a change (Command+B in Unity) (d) Observe that XCode project will have no signing certificate for GRPC-certificates, so you'll have to fix this manually (3 mouse clicks, and a scroll down to find the actual error in xcode's gargantuan list of warnings)

Have you been able to reproduce this issue with just the Firebase Unity quickstarts (this GitHub project)? What's the issue repro rate? (eg 100%, 1/5 etc)

100%

What happened? How can we make the problem occur?

If you have a downloadable sample project that reproduces the bug you're reporting, you will likely receive a faster response on your issue.

This can be reproduced on a blank project with the above packages.

// TODO(you): code here to reproduce the problem
paulinon commented 1 year ago

Hi @ferretnt,

Thanks for reporting this issue. I'm currently replicating this, but I'm not sure if I'm facing the same behavior that you're experiencing. That said, I have a few things to ask:

ferretnt commented 1 year ago

@paulinon Thanks for the response. I uploaded a very basic public repro here to demonstrate the problem.

https://github.com/ferretnt/FirebaseBuildRepro

You'll see that it's basically a bare Unity project with 4 firebase packages plus PlayServicesResolver added as tgz files - they're checked into the GooglePackages folder.

Build an run this project from Unity and you will notice that the first time you build you will have to fix two issues:

(1) GRPC-Certificates needs to have a development team manually assigned in XCode even if you've set your development team in Unity.

Screenshot 2023-03-07 at 2 32 14 PM

(2) An xcode error message which is not immediately obvious from the screenshot, but is saying "hey, your unity app is built with bitcode but some of the pods aren't." This can be fixed with a simple click to disable Bitcode in XCode, or via a buildpostprocessor script in Unity, but note that once this error is fixed once in XCode, it "stays fixed" until you do a full rebuild in Unity, or change build folder.

With that set, you'll be able to build and run to device. (In the screenshots I built to my macbook M1, but the flow is identical on iOS device.)

Now, switch to unity, modify any script or scene, hit cmd+B in Unity (incremental build and run) and note that you will once again have to re-assign the development team for grpc-certificates, which is very annoying. It seems that, ideally, the development team should be auto-set if you are using automatic signing and have set a team ID for the project in Unity, and minimally that it should not be cleared on every incremental build from Unity.

Screenshot 2023-03-07 at 2 34 01 PM
paulinon commented 1 year ago

Thanks for the additional information, @ferretnt. I've used the sample project you provided, but I still haven't encountered the behavior you're facing. It seems that none of the error messages you encountered appeared in any of the builds. It's quite odd that you're facing a bitcode-related issue considering bitcode inclusion in the SDK is discontinued starting version 10.1.0.

Could you provide the generated Podfile along with your iOS Resolver settings in Assets > External Dependency Manager > iOS Resolver > Settings? It would be great if you could also answer the questions in my previous response in order to identify what's causing your issue.

ferretnt commented 1 year ago

Hi @paulinon

A couple of clarifications to try to help. Firstly, to your original email:

When you mentioned that Xcode fails, are you referring to a failure in build? I was able to build the app successfully, but the app seems to have crashed immediately.

Yes, I'm referring to the fact that Xcode cannot build the project, because certain options are not configured correctly, specifically the signing team for grpc-certificates.

I am not sure why you are having runtime crashes - the project I sent you definitely runs directly on device (in fairness, it only contains one line of non-Firebase or default code, which is to make the cube spin just so I could see the app was running. To be clear, this issue can be reproduced with a minimal, blank, firebase project so you don't HAVE to use my project, which was really just the work to make such a project as a repro. I assume other users would have reported a bug if a blank unity project with fireabase SDK crashed on startup. To be clear, when you say "I was able to build the app successfuly", the first time you built the project from Unity, did it seamlessly perform Unity Build, Xcode build of the resulting xcworkspace, and iOS deploy with no user intervention? If so, that is surprising, and different from the behaviour I'm describing.

Could you clarify what these three clicks in the Xcode UI are as well as the actual error you're referring to?

I think I tried to clarify what I meant in the second email. I'm not sure it's exactly 3 clicks, but nontheless, any time you hit Cmd+B in Unity, the result will be an XCodeProj that cannot be built, because grpc-certificates does not have a development team assigned.

When rebuilding your Xcode project, do you select Append or Replace? Could you also confirm if performing one of these options results in a behavior different the other?

I'm hitting Cmd+B, which is equivalent to an incremental build, i.e. selecting Append. The behaviour also reproduces if you explicitly select file-->Build and Run with Append.

Thanks for the additional information, @ferretnt. I've used the sample project you provided, but I still haven't encountered the behavior you're facing. It seems that none of the error messages you encountered appeared in any of the builds. It's quite odd that you're facing a bitcode-related issue considering bitcode inclusion in the SDK is discontinued starting version 10.1.0.

To be clear, bitcode is not really the focus of this bug. Firebase does not include bitcode in its builds anymore. This is fine. Unity 2022.2.x still, by default, builds with bitcode enabled. This is arguably a poorly chosen default by Unity, but the only way that this is relevant to the real issue (grpc-certificates signing) is that if you fix the bitcode issue in XCode, it will then stay fixed (i.e. not be overwritten) by any other Build-And-Run operation, so you only have to fix it once. In other words, this is not a major workflow issue. By comparison, the fact that you have to reset your grpc-certificates team every single time you build incrementally from Unity is a more significant development workflow issue.

Could you provide the generated Podfile along with your iOS Resolver settings in Assets > External Dependency Manager > iOS Resolver > Settings? It would be great if you could also answer the questions in my previous response in order to identify what's causing your issue.

Oops, am typing this on my PC. Will switch to mac to grab them and add another comment with attachments.

ferretnt commented 1 year ago

Attaching podfile and screenshot of resolver settings (which should be the default - I haven't changed anything) here. Note that podfile has had .txt appended so that github will upload it.

Screenshot 2023-03-08 at 1 18 09 PM

Podfile.txt

a-maurice commented 1 year ago

So, I'm not sure how much can be done within the Unity SDK to fix this. I was able to reproduce this by just running pod install in the build directory as well, and it seems like almost any modification to the project results it it just reseting that field.

There was a report for the same issue on the iOS SDK, https://github.com/firebase/firebase-ios-sdk/issues/10411, that suggests a possible fix.

So, one possible workaround: 1) Run the Unity build once, to generate everything. 2) Edit the iOS project 3) Add the follow to the end of the Podfile:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
        target.build_configurations.each do |config|
            config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
        end
      end
    end
  end
end

4) In Unity, in the iOS resolver settings, uncheck the Podfile Generation item at the top. This will prevent the incremental build from regenerating the Podfile, which would undo step 3.

Doing that seems to have prevented it from reseting the gRPC certificate. The problem with this is if you ever do need to do a clean build, you have to remember to do all this set up.

A more stable option, if you want: You could add a build step to edit the Podfile. For reference, order of operations that the iOS resolver that currently generates the Podfile uses is here: https://github.com/googlesamples/unity-jar-resolver/blob/master/source/IOSResolver/src/IOSResolver.cs#L412

So you could add something between 40 (when it makes the Podfile) and 50 (when it runs pod install) to append the Podfile with those lines from above.

ferretnt commented 1 year ago

Thanks @a-maurice and @paulinon

In the immediate term (i.e. today) I'll do as you said, and after building the first time modify podfile and disable generation. Thanks! This will work for now for local iteration for the small number of our team members that actively iterate on iOS. The cost/benefit of the second solution doesn't seem worth it for us, although I'm surprised more firebase users aren't unhappy about this, especially given it also affects the native iOS SDK (maybe I'm just a luddite who still iterates on my device when writing code instead of pushing to a devops cloud build system and getting an artefact to test?)

Just wanted to check my understanding of the deeper threads. I'm not sure what KMP is (Kotlin Multiplatform?), but after tracing through the links in various issues down to here, my understanding is...

  1. This is an issue affecting iOS firestore platform
  2. It is caused by a file (grpc-certificates bundle) that firestore doesn't need being included by ??something, although I wasn't clear who needed to make a commit to remove it.
  3. That files will be (??has been??) removed from the iOS SDK
  4. Once all the dependencies bubble through (Firebase Unity release using Firebase iOS release etc) this will be resolved?

tl;dr:L Are all the wheels turning somewhere to resolve this, so at some point it will be fixed?

https://github.com/uhooi/firebase-ios-sdk/commit/28ee475a0fd71e587633c6a80edf25f73f958ec9

This issue is closed, although I wasn't clear if it was resolved? https://github.com/firebase/firebase-ios-sdk/issues/10411

This issue is still open though, so not sure.

https://github.com/firebase/firebase-ios-sdk/issues/9184#issuecomment-1007864247

hsallander commented 1 year ago

I have the same issue in our project. I'm on an M1 Mac, using cocoapods 1.11.3 via brew.

The project is using Unity 2021.3.17f1 and the following Firebase packages (as tgz files) :

com.google.external-dependency-manager-1.2.175
com.google.firebase.analytics-10.6.0
com.google.firebase.app-10.6.0
com.google.firebase.auth-10.6.0
com.google.firebase.crashlytics-10.6.0
com.google.firebase.dynamic-links-10.6.0
com.google.firebase.firestore-10.6.0
com.google.firebase.functions-10.6.0
com.google.firebase.remote-config-10.6.0
com.google.firebase.storage-10.6.0

I get both the abovementioned errors

ferretnt commented 1 year ago

Thanks for confirming. My personal feeling is that this issue should focus only on the gRPCCertificates issue, because that's the one that's disruptive to build workflow and nontrivial (as pointed out by @a-maurice above) to fix locally.

In retrospect, I wish I hadn't mentioned bitcode. The bitcode issue is a result of Unity's decision to have bitcode on by default (which although Apple's recommendation doesn't align with anyone's reality). Also disabling bitcode can be done by by adding an OnPostprocessBuild step to the unity project. Why there still isn't a "disable bitcode" option in PlayerSettings (or just disable it by default) I don't know, but a fix like this solves the bitcode issue permanently.

https://support.unity.com/hc/en-us/articles/207942813-How-can-I-disable-Bitcode-support-

a-maurice commented 1 year ago

Yeah, the bitcode thing is definitely outside our control. Looking more into the gRPC issue, I'm still struggling to see where exactly the problem lies, if it is something in the Firebase iOS side, or the gRPC side, but am reaching out to folks. We could potentially add a workaround in the Unity SDK, though I'm not entirely sure what the other implications of adding that code block might have to projects.

hsallander commented 1 year ago

I did some more testing today and it seems to possibly be Xcode version dependent. Could that be, @a-maurice? I haven't tested with different Xcode versions myself locally, but using our Unity Cloud Build pipeline I have been able to do some tests. All tests using Xcode 14 (current released Xcode is 14.2 as of this writing) or above failed with this error, and all tests using Xcode 13 succeeded.

Tested Xcode versions:

a-maurice commented 1 year ago

It definitely could, Xcode tends to change a lot of those settings between versions (like bitcode is no longer an option with Xcode 14).

Still reaching out to folks about it on my end, but the general consensus seems to be that the gRPC-C++-gRPCCertificates-Cpp shouldn't even be needed, and it is just getting added by one of the underlying dependencies. So one possible course of action would be to delete it. Though I suspect it would keep coming back when doing an incremental build (unless you disable the Pod step again).

vg-swift commented 1 year ago

Just switched to Xcode 14.1 and our builds started to fail with this error Signing for "gRPC-C++-gRPCCertificates-Cpp" requires a development team. Select a development team in the Signing & Capabilities editor. (in target 'gRPC-C++-gRPCCertificates-Cpp' from project 'Pods')

FYI, we're building with Unity Cloud Build

Seems like this is related: https://github.com/firebase/firebase-ios-sdk/issues/10411

vg-swift commented 1 year ago

Apple will enforce Xcode 14.1 starting April, so I assume this issue will become critical very soon

vg-swift commented 1 year ago

Seems like, from the other thread, the solution is to ignore gRPCCertificates-Cpp.bundle, but as it's generated/added by cocoapods (correct me if I'm wrong), what would be the solution for Unity (automatic builds)?

hsallander commented 1 year ago

Hi @a-maurice , do you have any news about this issue?

vg-swift commented 1 year ago

Wanted to update that we tested different Firebase versions starting with Firebase 10.0.1, and this issue happens on all version up to the latest 10.6.0. Also for us it happens not only on incremental builds but on clean builds as well (UCB), so currently we are unable to make any builds in the UCB using Xcode 14.1.0 due to this issue

vg-swift commented 1 year ago

This solution fixed it for us: https://forum.unity.com/threads/ios-failed-to-archive-on-xcode-14-1-14-2.1416096/#post-8929385

adaneko commented 1 year ago

We are also now having this problem. Is there any solution?

@vg-swift in the linked thread, I cannot see what the solution is you're refering to. Could you clarify what you did to make it work? I don't have Facebook SDK installed, and this seems to be a Firebase issue.

vg-swift commented 1 year ago

adaneko

In the end I had to switch to Ruby 2.7.4 on UCB. The Cocoapods update script is not necessary anymore, as Unity updated it on their side. And the last thing that I never mentioned, I had to downgrade Facebook to 11.0.0

adaneko commented 1 year ago

@vg-swift thanks for the reply. We were using a custom Gitlab based CI rather than UCB, so I had to add the "Code signing allowed = no" cocoapods script to that. Seems to be working now. :) For reference, we're using Ruby 2.7.6 and cocoapods 1.12.1. I have heard that it's possible that Apple will disallow builds with code signing off, so we'll see if it gets through.

ferretnt commented 9 months ago

I've been away doing enterprise dev with Azure SDKs for the last 9 months, but just returned to firebase development and was disappointed to see that this issue seems unchanged with Firebase SDK 11.6.0. There are several workarounds and maybe-someday fixes in the many messages above, but are there any plans to resolve this so you can build incrementally without having to reset the grpc-certificates development team every incremental build? Granted, for most local iteration disabling podfile generation (and enabling it every time you do a clean Unity build) works, but is exactly the type of extra-build-step-knowledge wart that plagues modern software development.

ferretnt commented 8 months ago

No response? Is nobody else bothered by this? Am I the last programmer alive who iterates by building and testing code locally?

ferretnt commented 5 months ago

Closing due to inactivity.