firebase / firebase/firebase-ios-sdk
Firestore cannot connect to the local emulator on iOS 26.5 (physical > device AND simulator) — works on the iOS 26.1 simulator with identical code. gRPC cleartext channel fails UNAVAILABLE while raw cleartext HTTP/2 from the same process succeeds
- Dominant language
- C++
- Stars
- 6.7k
- Forks
- 1.8k
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 75
Description
### Description
## ⚡ Controlled A/B (the headline)
Identical app build, identical emulator, identical host config:
| Environment | Result |
|---|---|
| iOS **26.1** simulator, `localhost:8080` | ✅ **WORKS** — writes land; a rules-denied probe read returns PERMISSION_DENIED (server round-trip proven) |
| iOS **26.5** simulator, `localhost:8080` | ❌ UNAVAILABLE, no traffic reaches the emulator |
| Physical iPhone 13, iOS **26.5.2**, LAN host | ❌ UNAVAILABLE, zero packets on the wire |
⇒ Regression in iOS **26.5** (runtime/network stack) × firebase-ios-sdk 12.15.0
(gRPC-C++ 1.69.0) cleartext channels.
## Environment
- firebase-ios-sdk **12.15.0 AND 12.16.0 — both reproduce** (gRPC-C++ 1.69.0 in
both; 12.16.0 retested 2026-07-16 on the iOS 26.5 simulator via
`$FirebaseSDKVersion` override: identical hang, zero traffic reaches the
emulator). Via FlutterFire: cloud_firestore 6.x, latest.
- Physical **iPhone 13, iOS 26.5.2**; Xcode 26.6; release build (XCUITest-driven)
- Firestore emulator (firebase-tools) on a Mac at `192.168.1.17:8080`, bound `0.0.0.0`
- App configured with `FIRFirestoreSettings.host = "192.168.1.17:8080"`, `sslEnabled = NO`
(equivalently `useEmulator` — both tried, identical result)
## Symptom
Every Firestore operation fails; the log repeats:
```
[FirebaseFirestore][I-FST000001] WatchStream (...) Stream error: 'Unknown: An internal error has occurred'
[FirebaseFirestore][I-FST000001] WriteStream (...) Stream error: 'Unknown: An internal error has occurred'
```
Dart-side (FlutterFire) surfaces `[cloud_firestore/unavailable]`.
**The same app on a physical Android device on the same Wi-Fi, against the same
emulator and host, works.** iOS Simulator with `localhost` also works.
### Reproducing the issue
## Repro sketch
1. Firestore emulator on a Mac, bound 0.0.0.0, note the Mac's LAN IP.
2. iOS app on a physical iOS 26 device: `settings.host = ":8080"`,
`sslEnabled = false`; perform any `getDocument`.
3. Observe UNAVAILABLE + zero connections arriving at the emulator, while a plain
`URLSession`/socket HTTP or h2c request from the same app reaches it fine.
## Evidence that the network path is NOT the problem
All probes run **from inside the failing app process** (dart:io = BSD sockets), at
the moment Firestore is failing:
| Probe | Result |
|---|---|
| HTTP/1.1 GET → `http://192.168.1.17:8080/` | ✅ 200 in ~20 ms |
| **Raw cleartext HTTP/2**: h2c preface + empty SETTINGS over a plain TCP socket to the same host:port | ✅ server replies with its SETTINGS frame |
| HTTPS GET → `https://firestore.googleapis.com/` | ✅ TLS fine |
| Firestore **default instance** (settings verified `host=192.168.1.17:8080 ssl=false`) | ❌ UNAVAILABLE |
| Firestore **fresh `instanceFor(databaseId:)` instance** (settings delivered at creation — rules out stale native settings) | ❌ identical UNAVAILABLE |
Wire-side observation on the Mac during a run (lsof sampling at 1 Hz + emulator
connection logs): **the Firestore gRPC channel sends zero packets to the host** —
no TCP connection to :8080 is ever attempted (the only connections logged are the
probes' own). The failure is generated on-device, before any wire contact.
## Ruled out
- iOS Local Network permission: granted (toggle ON; plain HTTP from the app works)
- ATS: `NSAllowsLocalNetworking` + `NSLocalNetworkUsageDescription` present (and IP
literals are ATS-exempt anyway)
- Wi-Fi HTTP proxy: off; same result
- `GRPC_CFSTREAM=0` (set via setenv before first Firestore use): no effect
- SDK version: already the newest pinned by current FlutterFire
## Suspicion
The gRPC transport used by Firestore on iOS 26 fails to establish a **cleartext**
channel to a **non-localhost** target on a physical device — reminiscent of the
iOS 18.4 simulator issue (#firestore emulator gRPC failure) that required a gRPC
bump. The channel appears to die before connecting (no packets), i.e. inside
transport/EventEngine setup rather than on the wire.
### Firebase SDK Version
12.15.0
### Xcode Version
26.6
### Installation Method
CocoaPods
### Firebase Product(s)
Firestore
### Targeted Platforms
iOS
### Relevant Log Output
```shell
```
### If using Swift Package Manager, the project's Package.resolved
Expand Package.resolved snippet
```json
Replace this line with the contents of your Package.resolved.
```
### If using CocoaPods, the project's Podfile.lock
I cut out a lot to stay under the body byte limit for this submission.
PODS:
- Firebase/Auth (12.15.0):
- Firebase/CoreOnly
- FirebaseAuth (~> 12.15.0)
- Firebase/CoreOnly (12.15.0):
- FirebaseCore (~> 12.15.0)
- Firebase/Firestore (12.15.0):
- Firebase/CoreOnly
- FirebaseFirestore (~> 12.15.0)
- Firebase/Functions (12.15.0):
- Firebase/CoreOnly
- FirebaseFunctions (~> 12.15.0)
- Firebase/Messaging (12.15.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 12.15.0)
- Firebase/Storage (12.15.0):
- Firebase/CoreOnly
- FirebaseStorage (~> 12.15.0)
- firebase_auth (6.5.3):
- Firebase/Auth (= 12.15.0)
- firebase_core
- Flutter
- firebase_core (4.11.0):
- Firebase/CoreOnly (= 12.15.0)
- Flutter
- firebase_messaging (16.4.0):
- Firebase/Messaging (= 12.15.0)
- firebase_core
- Flutter
- firebase_storage (13.4.3):
- Firebase/Storage (= 12.15.0)
- firebase_core
- Flutter
- FirebaseAppCheckInterop (12.15.0)
- FirebaseAuth (12.15.0):
- FirebaseAppCheckInterop (~> 12.15.0)
- FirebaseAuthInterop (~> 12.15.0)
- FirebaseCore (~> 12.15.0)
- FirebaseCoreExtension (~> 12.15.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GTMSessionFetcher/Core (< 6.0, >= 3.4)
- RecaptchaInterop (~> 101.0)
- FirebaseAuthInterop (12.15.0)
- FirebaseCore (12.15.0):
- FirebaseCoreInternal (~> 12.15.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreExtension (12.15.0):
- FirebaseCore (~> 12.15.0)
- FirebaseCoreInternal (12.15.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseFirestore (12.15.0):
- FirebaseCore (~> 12.15.0)
- FirebaseCoreExtension (~> 12.15.0)
- FirebaseFirestoreInternal (~> 12.15.0)
- FirebaseSharedSwift (~> 12.15.0)
- FirebaseFirestoreInternal (12.15.0):
- abseil/algorithm (~> 1.20240722.0)
- abseil/base (~> 1.20240722.0)
- abseil/container/flat_hash_map (~> 1.20240722.0)
- abseil/memory (~> 1.20240722.0)
- abseil/meta (~> 1.20240722.0)
- abseil/strings/strings (~> 1.20240722.0)
- abseil/time (~> 1.20240722.0)
- abseil/types (~> 1.20240722.0)
- FirebaseAppCheckInterop (~> 12.15.0)
- FirebaseCore (~> 12.15.0)
- "gRPC-C++ (~> 1.69.0)"
- gRPC-Core (~> 1.69.0)
- leveldb-library (~> 1.22)
- nanopb (~> 3.30910.0)
- FirebaseFunctions (12.15.0):
- FirebaseAppCheckInterop (~> 12.15.0)
- FirebaseAuthInterop (~> 12.15.0)
- FirebaseCore (~> 12.15.0)
- FirebaseCoreExtension (~> 12.15.0)
- FirebaseMessagingInterop (~> 12.15.0)
- FirebaseSharedSwift (~> 12.15.0)
- GTMSessionFetcher/Core (< 6.0, >= 3.4)
- FirebaseInstallations (12.15.0):
- FirebaseCore (~> 12.15.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (12.15.0):
- FirebaseCore (~> 12.15.0)
- FirebaseInstallations (~> 12.15.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- FirebaseMessagingInterop (12.15.0)
- FirebaseSharedSwift (12.15.0)
- FirebaseStorage (12.15.0):
- FirebaseAppCheckInterop (~> 12.15.0)
- FirebaseAuthInterop (~> 12.15.0)
- FirebaseCore (~> 12.15.0)
- FirebaseCoreExtension (~> 12.15.0)
- GoogleUtilities/Environment (~> 8.1)
- GTMSessionFetcher/Core (< 6.0, >= 3.4)
- Flutter (1.0.0)
PODFILE CHECKSUM: 1ae876023121e69222cd7d202ba5f1da5e511cf5
COCOAPODS: 1.16.2
Contributor guide
Assessment
This issue has not been assessed yet.