Firebase Firestore missing or insufficient permissions using Expo (React Native) - ios

I've been using FireStore for a project that works fine in the browser, but when I port the code to Expo, running on a iOS 11.2 iPhone X in the simulator, it keeps raising Error: Missing or insufficient permissions.
Auth is working fine, and when I check the client in the Firestore collection object, the appropriate UID is set, and testing the same code in the browser, everything works perfectly (no permissions problem). What I'm trying to say is that I'm 95% certain that the issue is with the Firebase lib/react native/expo combination, rather than with my code. Especially since it seems that making a call to Firestore in the browser, there are headers set, but when debugging the call in Reactotron (from Expo), it looks like the call the Firebase lib is making has no headers at all.
I doubt it makes a difference, but here are my auth rules:
service cloud.firestore {
match /databases/{database}/documents {
match /UserData/{userID} {
allow read, write: if request.auth.uid == userID;
}
match /MemberData/{userID} {
allow read: if request.auth.uid == userID;
}
}
}
The call I was trying to make (and there is definitely data in the doc) is the following:
profile = (await UserDataCollection.doc(`${idToken.uid}`).get()).data();
I'm curious if anyone else has run into this problem, and if so, are there any workarounds to make Firestore work?

As per previous comments, downgrading to 4.6.2 seems to fix the issue. I'm not sure the exact root cause but the behaviour of how the auth headers are sent seem to have changed (so potentially something there?). I'll update my answer if I get time to investigate further. Happy for one of the Firebase team to contact me for my account details if they want to verify on their side.

Related

Does electron's registerHttpProtocol work in development?

I'm trying to register a custom protocol with electron. I want it to be a redirect location that a website can use to provide an api key (like myprotocol://example/payload=api-key). I have been using electron's registerHttpProtocol and also tried electron's interceptHttpProtocol.
But, when the website tries to redirect to my protocol my electron app doesn't do anything. The website goes to myprotocol://example/payload=api-key, and registers a "page doesn't exist error"--while nothing happens in my app.
This is in a development environment. I've seen some discussion about custom protocols that assume a production environment.
Can you register a custom protocol with electron in development?
Why am I not able to intercept the website's going to the protocol I've set out?
Here's my code:
main.js:
app.whenReady().then(() => {
protocol.registerHttpProtocol('examplep', (request, callback) => {
console.log("examplep", request);
callback('it-worked');
}, (error) => {
if (error) console.error('Failed to register protocol = ' + error)
})
protocol.interceptHttpProtocol("examplep", function (request, callback) { //I've tried both registerHttp... and interceptHttp... methods, so including both here; though I think in practice only one should be required
console.log('intercepted!' + request)
callback(request);
});
})
redirect url provided to website:
'http://examplep'
And I've whitelisted this url on the website itself.
I've also tried related methods registerStringProtocol, interceptStringProtocol, registerFileProtocol, and interceptFileProtocol, without success.
What am I missing?
Sounds like you need to support deep linking fora desktop app, which is done via a Custom URI Scheme and is registered with setAsDefaultProtocolClient.
When your Electron app starts up write this code to register the scheme, on the main side of your app:
const customScheme = 'x-mycompany-myapp';
app.setAsDefaultProtocolClient(customScheme);
The custom scheme can be tested from the command line like this, depending whether you are running macOS or Windows:
open x-mycompany-myapp:/some/location
start x-mycompany-myapp:/some/location
A web client will just invoke a URL as in this Javascript code of mine;
The notification will be received within the main side of your app and on Windows will attempt to create a new instance of the app, in which case you need to detect this condition, process the notification then cancel the new app instance.
On MacOS it will be received within the open-url event, so you register it like this:
app.on('open-url', this._onOpenUrl);
Once the main side of the Electron app has the notification, it needs to get the URL information and forward it to the renderer process. You can use ipcMain events for this.
Finally the code for receiving the notification in running instances and starting the app from a deep link are different.
EXAMPLE APP
Since the code is a little tricky, here is some example code that may be useful, to give you something to compare against. If it helps you can also run the app by following the instructions in the blog post:
Code
Blog Post
My use case is around receiving OAuth responses after signing in from the system browser. Hopefully you can borrow some ideas from it related to deep linking though.
INFO.PLIST
My understand is that in a development environment (on macOS) deep links work when the app is running, but if you stop the app and attempt a deep link it will not start the app.
You can only resolve this for a packaged app, which requires an info.plist. In my code sample the info.plist is generated from build protocol entries in the package.json file.
My code sample is packaged in a basic way by the Electron Packager, so when I run npm run pack, the app is built to a dist folder. I can then run the packaged version of the app and it gets registered with the system - as can be seen in the Default Apps tool. See screenshots in the blog post.
SECRETS
Secrets for a desktop app should be stored using operating system secure storage. There are screenshots of credential storage in the blog post.
On Electron, have a look at the keytar component - and this wrapper class of mine. I am storing tokens (strings) so you should be able to adapt the code for your API keys.

Firebase Authentication does not insert new values

I recently updated to the newest version of Xcode and I've got a lot of problems since then. I've a "Sign up" form where user can create a new account on the app but somehow it does not insert new values into the Authentication.
I commented out my code and just tried to run the normal create user function so my code looks like this right now:
Auth.auth().createUser(withEmail: txtfield_email.text!, password: txtfield_password.text!) { (adr, err) in
if let err = err{
print(err.localizedDescription)
}else{
print("Succeded creating a new user!")
}
}
So when I run the app it will go into the else and print out: "Succeded creating a new user!" but when I login to my Firebase account and check if any new values is added to the authentication the answer is no. Nothing is there.
I've updated all my pods including the Firebase and still does not work.
What could of happen? Why doesn't it run like normal?
Just to mention: I'm currently running it on the simulator (Not my own device). But like I said, nothing new is getting implemented in Authentication. (Everything worked perfectly fine before, but not after I updated...?)
I've been struggling on this for hours and hours. But once I posted this thread I found my solution.
If you find this error yourself the solution is.
Go to your console in Firebase and download the latest version of:
GoogleService-info.plist
And replace your current one with the latest.

Meteor absoluteUrl issue

I have read dozens of posts about absoluteUrl but still cannot get a clear understanding.
I want to use multiple apps point to the same server code base. Each app has an appId (for example: http://localhost:3000/app1). Based on this id, server will serve corresponding assets to that app.
On client code, I have:
Meteor.startup(function () {
console.log('client startup');
Meteor.absoluteUrl.defaultOptions.rootUrl = "http://localhost:3000/app1";
console.log(Meteor.absoluteUrl());
//this line prints out http://localhost:3000/app1
});
and then:
meteor run ios
However, on simulator, my app is empty/blank, because it still points to localhost:3000 i think, while i only have router for ':_appId'.
I also tried ROOT_URL=http://localhost:3000/app1 meteor run ios, but it also does not work.
My intention is to bundle different app with different rootURL (/app2, /app3, ..) but use the same server code base. How could I do that?
Thank you.

xcode apigee logInUserWithFacebook extra parameter?

I'm using Apigee for my iphone/ipad app.
Like many apps today, mine requires a login via Facebook and Apigee has a function specifically for this in the iOs framework, here's how it's called:
[ApigeeDataClient logInUserWithFacebook:[FBSession activeSession].accessTokenData.accessToken];
As far as my code goes, everything works well up until the above line. I'm receiving the following error.
Response: {"error":"invalid_request","error_description":"missing access token"}
However check out how the function is making the call (from the logs):
Synch outgoing call: 'https://api.usergrid.com/sgfishing/deepseafishing/auth/facebook?ql=fb_access_token=CAADrhKxrQp4BANfZCMuZBdOwUL9nc0H4VzZC1EXVLjABRbcrucTlUgwlKczFinl51GIWyBM5nlZBX1RF84azFAEOfChqN7vgSmvqgwybV8iPU2xjncZB9T5YTdY0pesJkHsSlvOafMhQ6MfIa6qdZCbTYBZCFB2oIPgEnro4runJKcqCy68wZCFQwyIzACVThAC3IEjZADs36hToQxhYZBzAWVhbKlcqJQsroZD'
I would like to bring your attention to this ...facebook?<b>ql=</b>fb_access_token=CAADrh....
I'm not sure why ql= is there, I've checked the definition of logInUserWithFacebook and ql= is nowhere to be found.
Any help would be greatly appreciated.
This is a bug in our iOS SDK. It has been fixed in version 2.0.9 of our SDK (released yesterday).
?ql= is typically used for query language statements see if there is any such code around in your program
This just a tip...may help

Single Sign-On in iOS App with Adobe AIR

I am trying to integrate Facebook SSO on my iOS Game that I'm developing using Flash (with AIR).
I'm using the only tutorial that I've found (it's a pretty good one):
http://www.saumitrabhave.com/2011/10/facebook-single-sign-on-for-air-ios.html
I've gone so far, and implemented the things there, but I'm stuck with getting the access token back to the app.
In the tutorial, the invoke method (which is called when Facebook authorization is complete and we're back to the app) is implemented as follows:
protected function onInvoke(e:InvokeEvent):void{
var str:String = e.arguments[0];
if(str && str.indexOf("fb"+APP_ID+"://") != -1 )
...
e.arguments is always an empty array and because of this, str is undefined. What can cause this behavior?
Thanks,
Can.
I've just found the solution (I've been trying to figure out for hours). The invoke method is somehow called twice, and I was just checking the first one (without realizing that there even is a second call) and because it wasn't working, I was terminating the app without checking anything else afterwards.
For future reference: Invoke event may be called twice, the first one doesn't have the auth token sent, but the second one has.

Resources