Description
I've discovered a problem when querying Firestore from UWP Universal Javascript project with Firebase JS SDK.
Problem description
Problem occurs when querying Firestore with authenticated user and Firestore Security Rules set to:
service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth.uid != null; } } }
I'm always receiving:
FirebaseError: [code=permission-denied]: Missing or insufficient permissions.
With try and fail method I was able to find out that 'request.auth' object is 'null' in Security Rules because with following rule I'm able to successfully query Firestore:
service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth == null; } } }
However this Security Rule enables reading of data for everyone and stored data will not be secured.
In my opinion, the problem is related to the fact that access token is not processed (therefore request.auth is null). The only difference I've found is that HTTP header is NOT 'Origin: file://' (Origin header is completely missing) and CORS headers are not set correctly set in Response (CORS header are missing, but I'm not sure if this is the reason why access token is not processed).
Expected behavior
Auth token should be processed and Firestore Security Rules applied accordingly.
Attachements
UWP Project to reproduce the error (need some Firebase Test project and Firebase user):
https://1drv.ms/u/s!AjL4mBIpdvWDnYZqNkla5hHjjguGVg
HTTP Request from UWP:
Request URL: https://firestore.googleapis.com/google.firestore.v1beta1.Firestore/Listen/channel?database=projects%2__project__%2Fdatabases%2F(default)&VER=8&RID=21133&CVER=22&X-HTTP-Session-Id=gsessionid&%24httpHeaders=Authorization%3ABearer%20__access-token__%0D%0AX-Goog-Api-Client%3Agl-js%2F%20fire%2F5.7.2%0D%0A&zx=7qsckzfmr536&t=1 Request Method: POST Status Code: 200 / - Request Headers Accept: */* Accept-Encoding: gzip, deflate, br Accept-Language: en-US, en; q=0.7, cs; q=0.3 Cache-Control: no-cache Content-Length: 662 Content-Type: application/x-www-form-urlencoded Host: firestore.googleapis.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; MSAppHost/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134 - Response Headers alt-svc: quic=":443"; ma=2592000; v="44,43,39,35" cache-control: private content-encoding: gzip content-length: 71 content-type: text/plain; charset=utf-8 date: Tue, 01 Jan 2019 19:15:19 GMT server: ESF x-client-wire-protocol: h2 x-content-type-options: nosniff x-frame-options: SAMEORIGIN x-http-session-id: GDPR57fJd-FfP6jaM98wCUpOO9SWVFty x-xss-protection: 1; mode=block
Javascript Console output:
Initializing firebase main.js (49,5) Signing in main.js (55,5) Signed in. Uid is G3nVlgyQIcWai7TN6nbBnmiJfBF2 main.js (69,9) [2019-01-01T18:51:44.184Z] @firebase/firestore: Firestore (5.7.2) [FirestoreClient]: Initializing. user= G3nVlgyQIcWai7TN6nbBnmiJfBF2 firebase-firestore.js (1,605) [2019-01-01T18:51:44.186Z] @firebase/firestore: Firestore (5.7.2) [MemoryPersistence]: Starting transaction: Get last stream token firebase-firestore.js (1,605) [2019-01-01T18:51:44.186Z] @firebase/firestore: Firestore (5.7.2) [MemoryPersistence]: Starting transaction: Get next mutation batch firebase-firestore.js (1,605) [2019-01-01T18:51:44.188Z] @firebase/firestore: Firestore (5.7.2) [MemoryPersistence]: Starting transaction: Allocate query firebase-firestore.js (1,605) [2019-01-01T18:51:44.188Z] @firebase/firestore: Firestore (5.7.2) [MemoryPersistence]: Starting transaction: Execute query firebase-firestore.js (1,605) [2019-01-01T18:51:44.189Z] @firebase/firestore: Firestore (5.7.2) [MemoryPersistence]: Starting transaction: Remote document keys firebase-firestore.js (1,605) [2019-01-01T18:51:44.189Z] @firebase/firestore: Firestore (5.7.2) [Connection]: Creating WebChannel: https://firestore.googleapis.com/google.firestore.v1beta1.Firestore/Listen/channel [object Object] firebase-firestore.js (1,605) [2019-01-01T18:51:44.195Z] @firebase/firestore: Firestore (5.7.2) [Connection]: Opening WebChannel transport. firebase-firestore.js (1,605) [2019-01-01T18:51:44.196Z] @firebase/firestore: Firestore (5.7.2) [Connection]: WebChannel sending: {"database":"projects/xxx/databases/(default)","addTarget":{"query":{"structuredQuery":{"from":[{"collectionId":"settings"}],"where":{"fieldFilter":{"field":{"fieldPath":"createdBy"},"op":"EQUAL","value":{"stringValue":"G3nVlgyQIcWai7TN6nbBnmiJfBF2"}}},"orderBy":[{"field":{"fieldPath":"__name__"},"direction":"ASCENDING"}]},"parent":"projects/xxx/databases/(default)"},"targetId":2}} firebase-firestore.js (1,605) [2019-01-01T18:51:44.390Z] @firebase/firestore: Firestore (5.7.2) [Connection]: WebChannel transport opened. firebase-firestore.js (1,605) [2019-01-01T18:51:44.496Z] @firebase/firestore: Firestore (5.7.2) [Connection]: WebChannel received: {"targetChange":{"targetChangeType":"ADD","targetIds":[2]}} firebase-firestore.js (1,605) [2019-01-01T18:51:44.652Z] @firebase/firestore: Firestore (5.7.2) [Connection]: WebChannel received: {"targetChange":{"targetChangeType":"REMOVE","targetIds":[2],"cause":{"code":7,"message":"Missing or insufficient permissions."}}} firebase-firestore.js (1,605) [2019-01-01T18:51:44.653Z] @firebase/firestore: Firestore (5.7.2) [MemoryPersistence]: Starting transaction: Release query firebase-firestore.js (1,605) error on snapshot FirebaseError: [code=permission-denied]: Missing or insufficient permissions. main.js (81,17) "error on snapshot" { [functions]: , __proto__: { }, code: "permission-denied", description: "Missing or insufficient permissions.", message: "Missing or insufficient permissions.", name: "FirebaseError", stack: "FirebaseError: [code=permission-denied]: Missing or insufficient permissions. at e (https://www.gstatic.com/firebasejs/5.7.2/firebase-firestore.js:1:71386) at t.prototype.fromRpcStatus (https://www.gstatic.com/firebasejs/5.7.2/firebase-firestore.js:1:138184) at t.prototype.fromWatchChange (https://www.gstatic.com/firebasejs/5.7.2/firebase-firestore.js:1:147575) at e.prototype.onMessage (https://www.gstatic.com/firebasejs/5.7.2/firebase-firestore.js:1:262030) at Anonymous function (https://www.gstatic.com/firebasejs/5.7.2/firebase-firestore.js:1:260812) at Anonymous function (https://www.gstatic.com/firebasejs/5.7.2/firebase-firestore.js:1:261598) at Anonymous function (https://www.gstatic.com/firebasejs/5.7.2/firebase-firestore.js:1:169060)" }