firebase / firebase/firebase-unity-sdk

[Bug] iOS Phone Auth fails with about:blank on Unity 6 (6000.0.68+) due to UnityScene not forwarding URLs to FIRAuth

Open
#1,447 6 comments 0 reactions 0 assignees View on GitHub
api: auth type: bug
Dominant language
C#
Stars
320
Forks
60
Avg merge
11h 15m
Merged PRs (30d)
11

Description

### Description

## Summary

iOS Phone Authentication fails on Unity 6 (6000.0.68f1 and later). After the user completes the reCAPTCHA image challenge, the SafariViewController gets stuck at `about:blank` and the SMS code is never sent. No errors are logged.

## Root Cause

Starting from Unity **6000.0.68f1**, Unity automatically inserts `UIApplicationSceneManifest` into `Info.plist` to support Apple's UIScene-based lifecycle (in preparation for the future iOS UIScene requirement). With this manifest, iOS routes incoming URLs to `UnityScene.scene(_:openURLContexts:)` instead of the legacy `AppDelegate.application(_:open:options:)`.

However, `UnityScene` does not forward received URLs to the AppDelegate chain. Since Firebase Auth's swizzling mechanism hooks into the AppDelegate chain (and cannot intercept UISceneDelegate methods due to Apple's architecture), the reCAPTCHA callback URL never reaches `FIRAuth`, leaving the SafariViewController stuck at `about:blank`.

This is documented for native iOS developers at https://firebase.google.com/docs/auth/ios/phone-auth (see the SceneDelegate snippet calling `[FIRAuth.auth canHandleURL:url]`), but **the equivalent handling is not provided in the Firebase Unity SDK**, and the Unity Phone Auth documentation (https://firebase.google.com/docs/auth/unity/phone-auth) does not mention this requirement.

## Workaround

Removing `UIApplicationSceneManifest` from `Info.plist` via a PostProcessBuild script restores the legacy AppDelegate routing and fixes the issue:

```csharp
[PostProcessBuild(999)]
public static void OnPostProcess(BuildTarget target, string path)
{
if (target != BuildTarget.iOS) return;
var plistPath = path + "/Info.plist";
var plist = new PlistDocument();
plist.ReadFromFile(plistPath);
if (plist.root.values.ContainsKey("UIApplicationSceneManifest"))
plist.root.values.Remove("UIApplicationSceneManifest");
plist.WriteToFile(plistPath);
}
```

This is a temporary workaround that will not survive Apple's UIScene mandate (expected in the iOS release following iOS 26).

## Related Issues

- Unity Issue Tracker UUM-135497 (partially fixed in 6000.0.71f1, but URL forwarding to AppDelegate chain still missing): https://issuetracker.unity3d.com/issues/ios-application-dot-deeplinkactivated-does-not-get-invoked-while-app-is-running-when-uiapplicationscenemanifest-is-added-in-info-dot-plist
- Firebase iOS SDK Issue #4415 (AppDelegate proxy swizzling does not work with SceneDelegate): https://github.com/firebase/firebase-ios-sdk/issues/4415
- Firebase iOS SDK Release 11.2.0 (Phone Auth + SceneDelegate fixes for native iOS): https://github.com/firebase/firebase-ios-sdk/releases/tag/11.2.0

## Request

Please consider adding UIScene support to the Firebase Unity SDK so that URL handling required by Firebase Auth works out of the box on Unity 6 projects. This will also become mandatory once Apple enforces the UIScene lifecycle in a future iOS release.

Other SDKs (e.g., AppLovin MAX's ATT prompt flow) appear to be affected by the same UIScene transition, suggesting this is a broader concern for Unity iOS apps.

### Reproducing the issue

**Environment**
- Unity 6000.0.72f1 (also reproducible on 6000.0.68f1 through latest; NOT reproducible on 6000.0.67f1 or earlier)
- Xcode 16.1
- iOS device (real device required — Phone Auth cannot be tested on simulator)

**Steps**

1. Create a Unity 6 project (6000.0.68f1 or later) with Firebase Auth installed.
2. Configure Firebase Phone Authentication in the Firebase Console (enable Phone provider, set SMS region policy, upload APNs key).
3. Implement Phone Auth via `PhoneAuthProvider.VerifyPhoneNumber` in Unity.
4. Build for iOS with Xcode 16.x and deploy to a real device.
5. Run the app and trigger the phone authentication flow with a real phone number.
6. The reCAPTCHA WebView opens. Complete the image challenge (e.g., "Select all images with cars").
7. Observe: After completing the challenge, the WebView navigates to a `firebaseapp.com` URL and then becomes stuck at `about:blank`. The SafariViewController is never dismissed, and no SMS is sent.

**Note:** Reproducible with both real phone numbers and test phone numbers configured in Firebase Console — test numbers still go through the reCAPTCHA flow and hit the same wall, indicating the issue is not in the SMS sending logic but in the URL callback handling.

**Expected behavior:** SafariViewController should dismiss automatically after reCAPTCHA succeeds, and the SMS verification code should be sent to the provided phone number.

**Actual behavior:** SafariViewController remains stuck at `about:blank`. No SMS sent. No errors logged.

### Firebase Unity SDK Version

12.10.0, 13.6.0

### Unity editor version

6000.0.72f1

### Installation Method

Unity Package Manager

### Problematic Firebase Component(s)

Analytics, App Check, Authentication, Crashlytics

### Other Firebase Component(s) in use

_No response_

### Additional SDKs you are using

_No response_

### Targeted Platform(s)

Apple Platforms

### Unity editor platform

Mac

### Scripting Runtime

IL2CPP

### Release Distribution Type

Pre-built SDK from https://firebase.google.com/download/unity

### Relevant Log Output

```shell

```

### If using CocoaPods for Apple platforms, the project's Podfile.lock

Expand Podfile.lock snippet

```yml

👀 Replace this line with the contents of your Podfile.lock!

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.