I was having an issue with Firestore on iOS bypassing security rules on a collection when I converted from a get(), to a onSnapshot() listener.
I have confirmed my rules are working correctly via the get() in iOS, and both the get() and onSnapshot() listener work correctly in the Firebase JS SDK and Android SDK.
Again, these work correctly on the Firebase JS SDK, Android SDK and for get() on iOS, but not for onSnapshot().
service cloud.firestore {
match /databases/{database}/documents {
match /orders/{orderId=**} {
allow read: if request.auth.uid == resource.data.user.id;
allow write: if false;
}
}
}
firestore.collection('orders')
.where('user.id', '==', user.uid)
.get().then(snapshot => {
console.log('Snapshot: ', snapshot);
}, function(err) {
console.log('Error: ', err);
})
This should fail since I did not specifiy a user.id, as required by the rules. Instead, this gives me all the orders. This does correctly return Error: Missing or insufficient permissions. on the Firebase JS & Android SDK.
One odd note, is it does fire both the snapshot sending the data, but then it does sometimes call err and give the error. But, it always sends the data regardless.
firestore.collection('orders')
//.where('user.id', '==', user.uid)
.onSnapshot(snapshot => {
console.log('Snapshot: ', snapshot);
}, function(err) {
console.log('Error: ', err);
})
@brianhiss Another strange one you've stumbled upon. However, we have no way to bypass security rules with RNFirebase so this sounds like it might be an issue with the underlying Firestore iOS SDK. Have you raised an issue with them?
The only reason security rules wouldn't apply is if the phone was offline and had some data already cached?
@chrisbianca I figured it's on their end, but thought I'd report it and see if you guys came across anything similar.
It is really odd behavior, you wouldn't think you could bypass from a client, but that seems to be what I'm experiencing. Don't think it's from offline, but I'll make sure to rule that out.
I'll post back what I hear from them.
I can't say we've seen this, but we're not using Firestore extensively in our apps yet. We'll keep an eye out for it though.
Do let us know what they say...
@Salakar @chrisbianca Do you guys plan on supporting enableLogging(true); for Firestore as well, like you did with the Realtime Database (#525)?
The feedback I received from Google was to: "Capture a log where you get up-to-date data back (guaranteed not to be from cache) by calling Firestore.enableLogging(true)."
I've been digging around and it doesn't seem this is supported in react-native-firebase just yet, but might be an easier addition?
@brianhiss sure, just pushed something up to master for this if you'd like to pull from master,
firebase.firestore.enableLogging(true);
@Salakar Great, I'll check it out. Thank you!
@Salakar I tried to test master, but I keep getting a Unable to resolve modulereact-native-firebase, when I installyarn add https://github.com/invertase/react-native-firebase.git#master`.
Even when I clear watchman watch-del-all & npm start -- --reset-cache.
I'm able to install yarn react-native-firebase@next, but your changes aren't in there. I can manually copy them over and test, but wondering why it won't install from Github directly.
@brianhiss just found those issues myself - was from an internal restructure to support flow better, have just pushed fixes to the imports now - sorry 馃檲
@Salakar No problem.
The firebase.firestore.enableLogging(true); didn't seem to make a difference for cached data, but I was able to hack around and find the data I'm seeing for this issue is in fact cached, but it didn't show that way originally, even on a new install. Might have been a prior issue before a pod update, or need to include { includeQueryMetadataChanges: true } in my .onSnapshot() listener.
That being said, do you plan on supporting turning off data persistence in Firestore? I know it's on by default, but there is way to turn it off.
FIRFirestoreSettings *settings = [[FIRFirestoreSettings alloc] init];
settings.persistenceEnabled = NO;
// Any additional options
// ...
// Enable offline data persistence
FIRFirestore *db = [FIRFirestore firestore];
db.settings = settings;
@brianhiss I think the purpose of what google suggested was to get logs around your data via enableLogging calling that should have given more verbose logging on xcode log output, I guess they want a copy of this to debug their end.
RE FIRFirestoreSettings, definitely will be adding support.
@brianhiss FYI, we are tracking discrepancies against the web SDK:

Some of the stuff we haven't yet got to, e.g. transactions, others hasn't been done because the native SDKs differ from the web SDKs and it's a case of deciding the best way to structure the SDK to support both.
@chrisbianca Thank you for that. I did see you had a mention of it in your docs.
@Salakar Thank you for the quick turn around on this. I'm able to reproduce consistent results now by hacking out the cache. Seems there might have been some cached data even after deleting the app from the iOS simulator.
I also wonder if I can disable offline persistence for my react-native-firestore app.
What I try to do is make my app to unable to send or cache when it's on offline and show error.
But I can't find the way that I see it can't be uploaded to firestore db now.
At that time, I want to show alert or something instead just storing data in cache and updating UI.
@benevbright Currently we don't have a way to disable persistence for firestore. It's on our roadmap but we haven't got to it yet
@chrisbianca Thanks for your response!
One more question, Is there a way to get "timeout callback" when we update, add and delete?
There is a promise callback for complete but none for timeout.
@chrisbianca
@benevbright no, this isn't something that's supported by the underlying API so we're not able to offer it. You'd have to implement something bespoke to handle timeouts specifically, or rely on the Promise error.
Again, thanks for your response! @chrisbianca
Is it possible to use enable logging for storage?
Most helpful comment
@benevbright no, this isn't something that's supported by the underlying API so we're not able to offer it. You'd have to implement something bespoke to handle timeouts specifically, or rely on the Promise error.