Description
[REQUIRED] Step 1: Describe your environment
- Xcode version: 11.3.1
- Firebase SDK version: 6.19.0
- Firebase Component: Auth, Firestore
- Component version: Auth: 6.19.0, Firestore: 6.19.0
- Installation method:
CocoaPods
[REQUIRED] Step 2: Describe the problem
Firestore Emulator Security Rule request.auth
is always null even after authed.
I tried it on Android project/emulator, and it works fine, so I suspect it is iOS SDK's bug.
Steps to reproduce:
I created the reproduced project: https://github.com/mono0926/firestore-emulator-sample
1. Prepare Firestore Emulator
Execute this:
git clone https://github.com/mono0926/firestore-emulator-sample.git
cd firestore-emulator-sample/firebase
firebase emulators:start
If you create your own Firebase project, these steps are needed:
2. Run iOS application
Execute this:
cd firestore-emulator-sample/iOS/
pod install
open EmulatorSample.xcworkspace
And Run app on iOS simulator, and push the button:
The error log will be output:
error: Optional(Error Domain=FIRFirestoreErrorDomain Code=7 "
false for 'get' @ L5" UserInfo={NSLocalizedDescription=
false for 'get' @ L5})
Relevant Code:
Security Rule
This security rule allows /users/{userId}
get
only if request.auth != null
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow get: if request.auth != null;
}
}
}
iOS initialization
At didFinishLaunchingWithOptions
, set to connect to Firestore emulator.
let settings = Firestore.firestore().settings
settings.host = "localhost:8080"
settings.isPersistenceEnabled = false
settings.isSSLEnabled = false
Firestore.firestore().settings = settings
iOS logic
Auth.auth().signInAnonymously
Firestore.firestore().collection("users").document(uid).getDocument()
@IBAction func buttonDidTap(_ sender: Any) {
Auth.auth().signInAnonymously { (result, error) in
assert(error == nil)
guard let result = result else {
assert(false)
return;
}
let uid = result.user.uid
print(uid)
Firestore.firestore().collection("users").document(uid).getDocument { (snap, error) in
// "snap: nil"
print("snap: \(snap?.data())")
// error: Optional(Error Domain=FIRFirestoreErrorDomain Code=7 "
// false for 'get' @ L5" UserInfo={NSLocalizedDescription=
// false for 'get' @ L5})
print("error: \(error)")
}
}
}
This should succeed without any errors because the user is authed and firestore security rule only checks request.auth != null
and this condition is satisfied.
If setting to connect to emulator codes is commented out, the app will connect to real Firestore backend(same security rule deployed), and it works as expected.