Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling Cloud Functions locally from iOS gives an "Insecure fetch request" error #7537

Closed
ir-fuel opened this issue Feb 16, 2021 · 15 comments · Fixed by #7545
Closed

Calling Cloud Functions locally from iOS gives an "Insecure fetch request" error #7537

ir-fuel opened this issue Feb 16, 2021 · 15 comments · Fixed by #7545

Comments

@ir-fuel
Copy link

ir-fuel commented Feb 16, 2021

[REQUIRED] Step 1: Describe your environment

  • Xcode version: 12.4
  • Firebase SDK version: 7.6.0
  • Installation method: Swift Package Manager
  • Firebase Component: Functions

[REQUIRED] Step 2: Describe the problem

When running the emulator locally and calling a HTTPS function, the console outputs the following message:

 Insecure fetch request has a scheme (localhost) not found in fetcher allowedInsecureSchemes ((
    http
)): localhost:5001/****/us-central1/testFunction

Steps to reproduce:

Create a cloud function:

Run the emulator locally

Setup the iOS app to call your function and call it

Relevant Code:

exports.testFunction = functions.https.onCall(async (data, context) => {
}
firebase emulators:start

on iOS:

            let functions = Functions.functions()
            functions.useEmulator(withHost: "localhost", port: 5001)

            functions.httpsCallable("testFunction").call([ ...
@google-oss-bot

This comment has been minimized.

@maksymmalyhin
Copy link
Contributor

@ir-fuel Sorry you have the issue.

I haven't had a chance to test it on my end but most likely App Transport Security restrictions. You can configure an exception for localhost for the dev build of your app to temporary bypass the restrictions for testing. The instructions how to do it are available in the section "Configure Exceptions Only When Needed; Prefer Server Fixes" of the App Transport Security article - configuring an exception for a single domain looks like the most relevant for your case.

Please let us know if it's helpful.

@ir-fuel
Copy link
Author

ir-fuel commented Feb 16, 2021

ATS has been disabled in my info.plist (aka Allow Arbitrary Loads is set to YES)

@maksymmalyhin
Copy link
Contributor

Thank you for quick response!

Could you please share NSAppTransportSecurity part of your Info.plist file. It looks like according to the docs the globalNSAllowsArbitraryLoads key may be ignored in some cases.

@ir-fuel
Copy link
Author

ir-fuel commented Feb 16, 2021

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>
@maksymmalyhin
Copy link
Contributor

@ir-fuel Let me try it on my end and get back to you.

@maksymmalyhin
Copy link
Contributor

@morganchen12 We should consider adding ATS info to the docs.

@ir-fuel
Copy link
Author

ir-fuel commented Feb 16, 2021

The docs are also a bit strange:

https://firebase.google.com/docs/functions/local-emulator#ios---swift

Instrument your app for HTTPS functions emulation
Each HTTPS function in your code will be served from the local emulator using the following URL format:

http://$HOST:$PORT/$PROJECT/$REGION/$NAME

For example a simple helloWorld function with the default host port and region would be served at:

https://localhost:5001/$PROJECT/us-central1/helloWorld

http -> https

@maksymmalyhin
Copy link
Contributor

@ir-fuel thank you for spotting it!

@peterfriese
Copy link
Contributor

Potential duplicate: #7538

@maksymmalyhin
Copy link
Contributor

@ir-fuel @peterfriese A couple changes I had to do to make emulator working for me:

  • with the current SDK implementation the host parameter should contain the protocol part as well, e.g.
functions.useEmulator(withHost: "http://localhost", port: 5001)
  • App Transport Security must be configured to allow local networking:
	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsLocalNetworking</key>
		<true/>
		<key>NSAllowsLocalNetworkingUsageDescription</key>
		<dict>
			<key>localhost</key>
			<dict>
				<key>NSIncludesSubdomains</key>
				<true/>
				<key>NSExceptionAllowsInsecureHTTPLoads</key>
				<true/>
			</dict>
		</dict>
	</dict>

Please let me know if these changes are sufficient for you as well.

@ir-fuel
Copy link
Author

ir-fuel commented Feb 17, 2021

I didn't need to change my "allow all" ATS setting, I did need to put this:

functions.useEmulator(withHost: "http://localhost", port: 5001)

And it works now.

BTW did some doc change recently? I'm pretty sure I didn't invent the code to connect to the local emulator myself, but if I check the todays today they state:

 Functions.functions().useFunctionsEmulator(origin: "http://localhost:5001")
@peterfriese
Copy link
Contributor

peterfriese commented Feb 17, 2021

Can confirm prefixing the host with http:// resolves the issue. I also didn't have to be as specific about ATS as you specified in your sample, @maksymmalyhin - Allow Arbitrary Loads works (but I agree it's overly broad).

@ir-fuel - the code snippet you see there (I guess you're referring to https://firebase.google.com/docs/emulator-suite/connect_functions) gets pulled in from a code snippet, which hasn't been changed recently.

@samtstern
Copy link
Contributor

The "http" prefix should not be required in useEmulator, that's a bug. So I'll fix that which means that the workaround presented in this Issue will break in the future (just FYI)

@maksymmalyhin
Copy link
Contributor

BTW did some doc change recently? I'm pretty sure I didn't invent the code to connect to the local emulator myself...

I think the confusion comes from the API docs. Sorry about that, it will be fixed.

@firebase firebase locked and limited conversation to collaborators Mar 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
6 participants