Should the GCM API Key kept secret? - android

As per the documentation:
Do not include the API key anywhere in your client code.
And it is the case in our current Android app -- the API Key is nowhere included in the code. However, for the new version 3.0.0 of com.google.gms:google-services library, it started throwing error Missing api_key/current_key without it, as discussed here: Missing api_key/current key with Google Services 3.0.0.
Also, Google's config generator https://developers.google.com/mobile/add?platform=android&cntapi=gcm includes the API Key in the google-services.json file.
Is it supposed to be kept secret? Or is it safe to include it in the client app?

The google-services.json file represents the configuration for all of the services available within Firebase. There are some services that require and "Android" API key. These are the API keys that you will find in the google-services.json file. Your app may or may not use these API keys depending on the Firebase APIs your app is using.
FCM has a "Server" API key that is used to send messages, this API key is NOT the key included in the google-services.json file. The server API key should never be included in your application. The google services plugin however does look for those Android API keys at build time and that could be the reason for your error, it is not because your FCM server API key is missing.

Answering my own question.
If I create a new test project on Firebase (https://console.firebase.google.com), it also includes the API Key into
google-services.json for Android app,
GoogleService-Info.plist for iOS app,
for Web App it even recommends to include the API key into my HTML.
Taken that HTML is definitely public, I'm pretty convinced now that it's not a secret.

If you are using GCM, your Android app need not know about the API key. I just had to include an empty field for api_key in the json file for GCM to work. As mentioned in tha answer here Missing api_key/current key with Google Services 3.0.0 and Maps API key in build.gradle, I just had to add a line like below in google-services.json for GCM to work:
"api_key": [
{
"current_key": ""
}
],
I think you shouldn't include the API key, since I think only your server needs API key to authenticate with Google for requesting it to send push messages to intended recepients. It would be a risk if anyone gets hold of it. So file can look like:
{
"project_info": {
...
},
"client": [
{
"client_info": {
...
},
"oauth_client": [
{
"client_id": "yourid.whatever.com",
...
}
],
"api_key": [
{
"current_key": ""
}
],
"services": {
...
}
}
],
"configuration_version": "1"
}
Hope this helps.

Related

Firebase cannot communicate with Firebase Server

I am using Firebase PhoneAuth and getting the following error.
Firebase Installations can not communicate with Firebase server APIs due to invalid configuration. Please update your Firebase initialization process and set valid Firebase options (API key, Project ID, Application ID) when initializing Firebase.
W/Firebase-Installations: Error when communicating with the Firebase Installations server API. HTTP response: [400 Bad Request: {
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google developers console",
"url": "https://console.developers.google.com"
}
]
}
]
}
}
]
Background
The error says that the API key you use when initializing Firebase is not accepted by Google. You might in fact be using an invalid API key or Google might incorrectly identify your API key as invalid. The latter can happen if your API key has not been used in a long time.
FirebaseInstallations is new infrastructure for Firebase services that makes use of the API key you use when initializing Firebase. If you recently updated your Firebase SDKs, FirebaseInstallations might have started using your API key which was not used before.
Remedy
If you have issues with your current API key, you can create a new API key in the Cloud Console:
go to the Google Cloud Console
choose the relevant project (i.e. the project you use for your application)
open the menu and go to APIs & Services → Credentials
on top of the page click on + CREATE CREDENTIALS → API key
replace the API key in your application with the newly created API key
google-services.json
In case you are using the google-services.json config file from your Firebase Console, you first have to delete or restrict the API key used in your current google-services.json in order to make Firebase update config file and use a new API key.
Identify the API key in your google-services.json config file.
Confirm that the API key is creating the erroneous requests by checking its usage against the Firebase Installations API metrics page. The column Usage with this service of your API key should show a number greater than 0.
Delete that API key by clicking the bin symbol or add Application restrictions to that API key by clicking the pencil symbol. !!Warning!! Do not delete an API key that existing installations of your applications require for other Firebase services like Firebase Auth or Realtime-Database.
Wait a couple of minutes for Google servers to update. The next download of your google-service.json config file should contain a new API key.
Links
Other relevant links regarding API keys and the Firebase Installations API:
https://firebase.google.com/support/privacy/init-options
https://github.com/firebase/firebase-android-sdk/blob/master/firebase-installations/API_KEY_RESTRICTIONS.md
https://firebase.google.com/support/release-notes/android#2020-02-27
In my case, after struggling 5 hours, finally I figured out that Firebase Installations communicate with Firebase server by wrong API key which exist in values.xml file in this path \app\build\generated\res\google-services\debug\values
not the API key in google-services.json file.
Because, I tried to run with updated google-services.json but it doesn't help.
So you should delete this values.xml file and it will be recreated again with the right API key automatically when you build and run.
Just delete this file and run.
If you are facing this issue in the Flutter app, then after updating the google-services.json file, you should delete the build folder from your project directory. Maybe it will work.
In my case, I have generated SHA1 key using :
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
after that add this key and package name into Restrict usage to your Android apps in Google Cloud
That's it !

How to force Google to refetch .well-known/assetlinks.json in order to fix my Android App Link implementation

I have successfully implemented Android App links with My Local APK and it works. When I published the same APK in Google Play Store I figured out that I need to change SHA 256 fingerprint in my /.well-known/assetlinks.json with the fingerprint provided by Google. So I changed it. Unfortunately it seems that Google keeps the old copy of assetlinks.json which brakes my app links.
I have checked
https://developers.google.com/digital-asset-links/tools/generator and it said
"No app deep linking permission found for [your-app]"
I have checked
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=[my-site]&relation=delegate_permission/common.handle_all_urls and it shows me the old version of assetlinks.json
My robots.txt
User-agent: *
Disallow:
My .htaccess file in directory /.well-known
Require all granted
RewriteEngine Off
<FilesMatch "\.(txt)$">
Require all granted
</FilesMatch>
<FilesMatch "\.(txt)$">
Allow from all
</FilesMatch>
My assetlinks.json
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target" : { "namespace": "android_app", "package_name": "my-app-id",
"sha256_cert_fingerprints": ["my-sha-256-provided-by-gogole-play-console"] }
}]
The result of https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=[my-site]&relation=delegate_permission/common.handle_all_urls
{
"statements": [
{
"source": {
"web": {
"site": "https://my-host."
}
},
"relation": "delegate_permission/common.handle_all_urls",
"target": {
"androidApp": {
"packageName": "my-app-id",
"certificate": {
"sha256Fingerprint": "the-old-sha-256-fingerprint"
}
}
}
}
],
"maxAge": "534347.929731888s",
"debugString": "********************* ERRORS *********************\nNone!\n********************* INFO MESSAGES *********************\n* Info: The following statements were considered when processing the request:\n\n---\nSource: Web asset with site https://my-host. (which is equivalent to 'https://my-host')\nRelation: delegate_permission/common.handle_all_urls\nTarget: Android app asset with package name my-app-id and certificate fingerprint the-old-sha-256 \nWhere this statement came from:\n Origin of the statement: Web asset with site https://my-host. (which is equivalent to 'https://my-host')\n Include directives followed (in order):\n \u003cNone\u003e\nMatches source query: Yes\nMatches relation query: Yes\nMatches target query: Yes\n\n--- End of statement list. ---\n\n\n"
}
The the-old-sha-256 is different from the SHA 256 in my actual assetlinks.json
P.S. my-app-id, my-host, [my-site] and so on are placeholders.
So... How to force Google to read my current assetlinks.json instead of using old cached version?
In your case, google cached your SHA256 and will take max limit
of eight days to update your SHA256. Just change the name of website
in the url given below, that will show you the SHA256 key google has
been cached.
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://www.your-website-name.com&relation=delegate_permission/common.handle_all_urls
The assetlinks.json file may also be cached by Play Services on your
device and also on Google’s servers, so it may take a few days for
them to be updated from any changes you make to your web servers. And
SmartLock chrome/app login sharing needs your APK to be downloaded
from Google’s app store.

E/TokenRequestor: You have wrong OAuth2 related configurations, please check. Detailed error: UNREGISTERED_ON_API_CONSOLE

I am using Google Sign In via Firebase in my app. But while running the published app from Play Store, it shows following error.
E/TokenRequestor: You have wrong OAuth2 related configurations, please check. Detailed error: UNREGISTERED_ON_API_CONSOLE
All though I have registered on Firebase, and API Console, with ids mentioned in JSON file. Following is the JSON File code
{
"project_info": {
"project_number": "311816357497",
"firebase_url": "https://mcqsce.firebaseio.com",
"project_id": "mcqsce",
"storage_bucket": "mcqsce.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:311816357497:android:494b736XXXX6010b",
"android_client_info": {
"package_name": "in.readhere.mcqceit"
}
},
"oauth_client": [
{
"client_id": "311816357497-9ma34c4qXXXXXXXXXXXXXoep8b24u8g.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "in.readhere.mcqceit",
"certificate_hash": "6847ce9f7e38dc588d12345678f21c13bd25ea7c"
}
},
{
"client_id": "311816357497-5lbqnmj0bxxxxxxxxxxxxxm4qjfhmq06.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyC6BGtRfxxxxxxxxxGrwwe_0V3uY9g-0dI"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 2,
"other_platform_oauth_client": [
{
"client_id": "311816357497-5lbqnmj0bxxxxxxxxxxxxxxm4qjfhmq06.apps.googleusercontent.com",
"client_type": 3
}
]
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}
Following is the API Console for app
firebase console
api console
After spending some time I figure it out what was the problem with Google sign in and why this error was throwing when I do Google sign in.
So here is the solution for this: In my case, I have published the apk on google play store and I have selected Google play app signing what that does it will create new certificate keystore for security purpose and the old keystore get invalid (https://support.google.com/googleplay/android-developer/answer/7384423) and you have added SHA1 in firebase for old keystore not for new one which is created by Google. So when you try logging in through google then it throws this error.
So i figure it out: Go to your Google play console(https://play.google.com/apps/publish/) > Select the App (on the left menu) > Release Management > App signing
You will see two app signing certificate one is your old uploaded keystore certificate and another one is the newly created app signing certificated created by google play. So copy the SHA1 and SHA256 key from App signing certificate and paste the same key in Firebase console (https://console.firebase.google.com) > Select your project > select app setting > General (Select your app package) > and paste the both SHA1 and SHA256 key and save and you are done.
Restart the app and it will work. It works in my case ;)
Please check your build variant [Release|Debug] .
Possible errors are :
you have added SHA1 for DEBUG and you build release apk or vice versa
You need to add SHA fingerprint for each android app on your project settings.for Firebase, edit the below link with your project's name and then add the fingerprint for your app.
https://console.firebase.google.com/project/{YOUR_PROJECT_NAME}/settings/general/
The complete recipe:
As the other answers, make sure that your actual signed Android apk has the same SHA fingerprint as what you specified in the console of your Firebase project's Android integration section (the page where you can download the google-services.json)
On top of that go to the Settings of your firebase project (gear icon right to the Overview at the top-left area. Then switch to Account Linking tab. On that tab link the Google Play to your project.
And voila! Hopefully your problem will be solved.
1)Just open below link of your google console account
https://console.developers.google.com/apis/credentials
2)select your project and done, try to login now (google automatically create credential based on your FCM project).
Only follow 3 step if you not created project in FCM
3)create a new Credentials / OAuth client id / Android, defined by the SHA1 fingerprint and your APK package name. Done
I had the same problem, the problems was security network in my phone. I fixed by removing the security network.
You need a SHA1 fingerprint for debug app and another one for release. Run this in a terminal to get the release fingerprint:
keytool -exportcert -list -v -alias <your-key-name> -keystore <path-to-production-keystore>
You will need your keystore password (the one you use to generate a signed APK).
Then go to https://console.firebase.google.com/project/_/settings/general/ and add the new fingerprint
I was having the same problem when trying to sign in with Google on a published app, and this fixed the problem

Where do I find the namespace of an app [Android]

I need to find the namespace of the app, so I can fill in the value for the assetlinks.json file.
https://www.domain1.com/.well-known/assetlinks.json
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.mycompany.app1",
"sha256_cert_fingerprints":
["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
}]
Tim, I was looking for this too because the Google docs never explained the namespace field in the json. As it turns out, you leave the value as android_app, this tells consumers these settings are specifically for an android_app. It is not to specify the specific namespace of your app or project (like I also assumed)
See https://firebase.google.com/docs/app-indexing/android/app
Target: Using the namespace value of android_app determines the android app that receives the URLs. Configure it using its package name and the SHA-256 fingerprint of the certificate you used to sign your app before deploying it to the Play Store. See Signing Your Applications to learn more about deployment and your signing certificate.
Thanks for the #johnw182 answer, just want to add, that wrong name leads to unpredictable errors and I spent a lot of time to find them.
But it is possible to validate the assetlinks.json file
Just change YOUR_WEB_SITE_ADDRESS to web-site with assetlinks.json file.
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://YOUR_WEB_SITE_ADDRESS&relation=delegate_permission/common.handle_all_urls

Android Google App Invite sample is not sending email and message,What i am doing wrong?

I am using Android Google App invite sample and following all guidelines but it is not sending any messages and emails, it gives message
Message Failed to Send
and in logs i am getting
onActivityResult: requestCode=0, resultCode=3`
getInvitation:onResult:Status{statusCode=CANCELED, resolution=null}
One possibility is an issue with your client configuration file. Make sure you followed Step 2: get a configuration file in the App Invites guide and have added the the google-services.json file to your project.
Check that package_name and certificate_hash match your credentials in Developers Console for the Default Demo App. Note: the certificate_hash will not have the colon delimiters.
// from: google-services.json
...
"oauth_client": [
{
"client_id": "<id>",
"client_type": 1,
"android_info": {
"package_name": "com.google.android.gms.samples.appinvite",
"certificate_hash": "<Signing-certificate fingerprint>"
}
}
],
In my case I was creating dubug build. But when I change Build variants from debug to release the problem solved.

Categories

Resources