CreateWalletObjectsRequest is missing from com.google.android.gms.wallet API - android

As per the given link: https://developers.google.com/wallet/objects/savetowalletnative
I am trying to run the sample application, but in this below method, I am not able to find CreateWalletObjectsRequest. It says:
"CreateWalletObjectsRequest cannot be resolved to a type"
public void saveToWallet(View view){
LoyaltyWalletObject wob = generateObject();
CreateWalletObjectsRequest request = new CreateWalletObjectsRequest(wob);
Wallet.createWalletObjects(googleApiClient, request, SAVE_TO_WALLET);
}

Google hasn't opened Save to Wallet api for everyone yet. We had to get a special Google Play Services AAR directly from Google, along with a lot of help from a Googler to get it functioning (the sample is out of date).

As of now, you'll need to work with your Google contact to get the second-party library to integrate Android Pay. Once you get the aar file, you can import it into your project and add it as a dependency.
Now, the 'createWalletObjects' method call in your question has shifted in its location and signature; its now as follows:
Wallet.WalletObjects.createWalletObjects(googleApiClient, request, SAVE_TO_WALLET);
The SAVE_TO_WALLET is the integer request code that you'll identify the request in your onActivityResult(). Creating the request as such is described in the "Create an object" section of https://developers.google.com/save-to-android-pay/guides/android/add-button-to-your-app

Related

Your app contains exposed Google Cloud Platform (GCP) API keys. Please see this Google Help Center article for details

My key is restricted using package name and SHA1, still Google Play store shows this warning.
Any idea why it is showing like this. I defined my API key in build.gradle file and using it from there.
As per google's recommendation putting restrictions such as specifying the package name and also the SHA-1 key is the way to go.
It has been explained here: https://cloud.google.com/docs/authentication/api-keys#securing_an_api_key
Now, the problem here is that whatever you do your API key will end up in the codebase i.e if you specify it outside your codebase (via some properties file) but pass it in via the BuildConfig field during the build phase (the whole key is visible to someone decompiling your code as it is now part of BuildConfig class file) or you split it up and concatenate in the codebase (the split keys are still visible and anyone can concatenate them by seeing the usage to get the final key from a decompiled apk).
The split key version will get rid of the warning in the Play Console, but the key is still exposed.
My suggested solution thus would be to encode your API key and pass that around your codebase. Just before using it you decode it back.
A very simple example can be:
Please use a better encoding algo and not this, this is for demonstration purpose only. Here we are using Base64 encoding.
import android.util.Base64
fun main() {
// API Key = "123456ABC"
val myEncodedApiKey = "MTIzNDU2QUJD" // Should be passed via BuildConfig
val decodedApiKey = Base64.decode(myEncodedApiKey, Base64.DEFAULT)
// Now use `decodedApiKey` in your codebase.
val decodedApiKeyString = String(decodedApiKey)
}
Why is this better?
Your key is not exactly the same as in your GCP project.
The play console when it scans your codebase, cannot match it back to your GCP project API keys. Thus no warnings.
Update (clarification on using the google-services.json file for API key):
The solution to use the API key from google-services.json isn't quite valid. google-services.json is generated file usually if you connect your firebase account. The API key defined there has a different restriction model. The one you define in your GCP project is different, allowing you to pass in package name and an SHA-1 key as well as restricted to a specific kind of API access such as Youtube only access. So if one was to use the API keys from google-services.json then you are essentially not using the restrictions you set up in your GCP account. GCP accounts do not generate google-services.json file.
To bring into perspective here is an official doc from Google for setting up Youtube API which uses GCP project defined API keys and in the docs, it mentions to directly put the keys in the code. (which is anyways wrong as it is exposed, but that's Google for you).
https://developers.google.com/youtube/android/player/setup
Nowhere in any docs, it is referred to use google-services.json file for retrieving API keys.
Got Google Play Ads? It would appear that, at least as of 8-1-19, an api key that triggers this is embedded within the full google play services ads library. That is--
implementation 'com.google.android.gms:play-services-ads:18.1.1'
triggers the alert, but
implementation 'com.google.android.gms:play-services-ads-lite:18.1.1'
which removes some code that already exists in the play store, does not. The error itself cites an obfuscated method, which I tracked down in the apk to:
com/google/android/gms/internal/ads/[obfuscatedstring]/<clinit>()
This appears to set a bunch of constants. One of which is called gads:safe_browsing:api_key
Just in case I'm wrong and this isn't in everyone's code I won't reproduce it here, but it sure looks to me like a GCP key that might trigger the issue. It is 40 characters and this identical key can be found elsewhere on the Internet.
My guess is, if you're using the play-services-ads library (as opposed to the Firebase library), it is probably seeing this string and sounding an alarm.
You can remove this warning by split your keys into 4 parts like this
public static final String API_KEY_PART_1 = "Asdsdfdd-";
public static final String API_KEY_PART_2 = "dfsFdsdsFdd";
public static final String API_KEY_PART_3 = "Pgdhs_SfSfs";
public static final String API_KEY_PART_4 = "fdfDDSD";
and use it by concatenate Strings
.attest(nonce.getBytes(), Constants.API_KEY_PART_1+Constants.API_KEY_PART_2+Constants.API_KEY_PART_3+Constants.API_KEY_PART_4)
NOTE: Make sure you restrict your API key to Applications Access only. otherwise if someone decompile your apk and use your api key then it may be increase your billing.
Restric your API's Key with SHA & Package name click here for details
Sorry, a bit late to the game here...
Follow the below steps:
The Firebase console will help you download the google-services.json. In addition, the Quickstart guides for most APIs have instructions for generating this file. Once you have downloaded the google-services.json file,copy it into the app/ folder of your Android Studio project, or into the app/src/{build_type} folder if you are using multiple build types.
The Google Cloud Console will help you to enable the GCP(ex: Places API,Map SDK for android etc.) in API Library section by choosing the project which was created in the Firebase console.
you could get the api key with:
activity.getResources().getString(R.string.google_api_key);
String key name is "google_api_key" for getting the API Key.
FYI, The google-services.json file gets parsed and its values get added to an xml (path: app/build/generated/res/google-services/{build_type}/values/values.xml) which you have access to: https://developers.google.com/android/guides/google-services-plugin
Sorry, a bit late as my previous answer was just bypass the warning after some research i found an appropriate fix for this problem
you can get api key from google json file.
The google-services.json file gets parsed and its values get added to an xml which you have access to all the elements of json as Android resources in your Java code click here for details
Below is an example to access the google api key from json file :
activity.getResources().getString(R.string.google_api_key);
better to use firbase firestore database to store your api key and access it. Firestore is safe and highly secure as its a product of Google.
and access it using this code
mDatabase.collection(COLLECTION_NAME)
.document("DOCUMENT_NAME")
.get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Log.d(TAG, "google_places_api_key: " + documentSnapshot.get("google_places_api_key") + "");
}
});
This method is safe and secure and your api key will not access by any Man in the middle attack and of course play store will allow this method.
it may be late, but will help some of the guys,
There is no link between Firebase JSON configuration file and google
maps integration API key
Firebase Clarification
If you integrate Firebase in your app, it requires the JSON configuration to be placed in your code, and this is the only way to connect the app with Firebase.
but in Google maps, it is totally different. It will provide the key - to place in our code but not hard-coded or as it is,
Solution:
I have combined both solutions to work around, from Nishant and Sahil Arora, to encode the key into something else and split it into pieces to make it somehow difficult to decode back, I am splitting into the four-part, you can as much as you feel good:
Decode your ApiKey
// getEncodedApiKey result encoded key,
// splitted into four the part
String thePartOne = "encodedPartOneMaybe";
String thePartTwo = "encodedPartNextMaybe";
String thePartThree = "encodedPartNextMaybe";
String thePartFour = "encodedPartLast";
public String getSplitedDecodedApiKey(){
return new String(
Base64.decode(
Base64.decode(
thePartOne +
thePartTwo +
thePartThree +
thePartFour ,
Base64.DEFAULT),
Base64.DEFAULT));
}
Encode your ApiKey
//just to encode the string before splitting it into the pieces
//and remove this method from the source code
public void getEncodedApiKey(){
String plainApiKey = "xiosdflsghdfkj"; //
String encodedApiKey = new String(
Base64.encode(
Base64.encode(plainApiKey.getBytes(),
Base64.DEFAULT),
Base64.DEFAULT));
Log.i(TAG, "getEncodedApiKey: " + encodedApiKey);
}
Had the same issue for a long time, in my case while initializing the Youtube Player with google api key.
It didn't go away even after restricting the API Key with SHA & Package name.
However, after migrating to androidX the Security alert is gone in Google Play Console.
This error comes when developers write the API keys exposed as hardcoded strings in Java or XML files. Use it inside a strings.xml. And reference it as mentioned below. It will get resolved automatically.
geoApiContext = new GeoApiContext.Builder()
.apiKey(getResources().getString(R.string.maps_api_key))
.build();
Add API_KEY in gradle.properties
API_KEY = **ADD_KEY_HERE**
Add the below line in the build.gradle(app) within the defaultConfig.
buildConfigField('String','GCP_API_KEY',API_KEY)
In code, we can use BuildConfig.GCP_API_KEY
I also encounter your app contains exposed gcp api key error issue on google play console and i tried following Steps :
Splitting the api key
moving the api key to string.xml file
but nothing worked as expected.
To Resolve your app contains exposed gcp api key error move your API key to android manifest file.
I move the API key to Android Manifest file and used that meta data to retrieve the API key from manifest file for initialisation.
Steps to use the api key from manifest file.
Add the API key in Manifest file
<meta-data
android:name="api_key"
android:value="api_key_value" />
Now it's time to use the api key from manifest file.
ApplicationInfo info = getJavaActivity().getPackageManager().getApplicationInfo(getJavaActivity().getPackageName(),getJavaActivity().getPackageManager().GET_META_DATA);
String apiKeyValue = info.metaData.getString("api_key"); // use the apiKeyValue to initialise your SDK
happy Coding :)

Firebase Management API projects.addFirebase permission denied

Problem: Firebase Management API method projects.addFirebase returns status code 403
Steps to recreate:
In an Android application I need to create separate Firebase Accounts for Realtime Database. For this purpose I authenticate users with GoogleSignIn.
Then I retrieve token with proper scope "oauth2:https://www.googleapis.com/auth/cloud-platform".
In next step I use GCP Resource Manager API to create a new GCP project, which will be a container for Firebase project.
The new project is created successfully on each of the test accounts.
When I try to call Firebase Management API method projects.addFirebase using the same token I got earlier (same scope) I get error "The caller does not have permission". This error occurs on 3 out of 4 accounts I have tried.
I was able to reproduce same error also using google-apis-explorer. Apis Explorer
I will be grateful for any hints on how to resolve this issue. As I mentioned earlier this error does not occur on one of the accounts I tested, while on the remaining three it happens every time.
Thank you.
Update
#Doug thank you for taking time to look at my problem. It seems that I have found the cause. After accessing https://console.firebase.google.com and clicking "Add a project" a following popup showed up (I can't paste it directly, because my reputation is too low):
Popup link
After I checked all consents and added first project I am also able to make api calls successfully.
It looks like I my question should be: Is there a way to grant required permissions through Resource Manager Api calls so I can add Firebase to existing Cloud Project?
Also for the reference I paste the method I use to call projects.addFirebase, it uses RxJava2 (Android) and Retrofit2.
#Headers({"Content-Type: application/json"})
#POST("projects/{project}:addFirebase")
Single<Operation> addFirebaseToProject(#Header("Authorization") String bearerToken,
#Path("project") String project,
#Body FirebaseDataModel dataModel
);
Thank you for your help.
Ps. sorry for my bad English, it's not my mother tongue.

Firebase authentification works but I get error when using the Google Text to Speech API

I've set up a small android and firebase app... Authentification works like a charm, and in the firebase console, I can see my user, logged in with the Google account.
Now I am trying to experiment a little with the Text to Speech api, and in doing so, I followed this tutorial:
https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/texttospeech/cloud-client
I managed to make the small java app work, by setting the GOOGLE_APPLICATION_CREDENTIALS Environment variable (I followed this tutorial for this step: https://cloud.google.com/docs/authentication/getting-started), but I am not sure what I need to do to make that code work in the Android app where the users are authentificated..
The Error that I get when trying to make a call to the TextToSpeech API is:
The Application Default Credentials are not available. They are
available if running in Google Compute Engine. Otherwise, the
environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined
pointing to a file defining the credentials. See
https://developers.google.com/accounts/docs/application-default-credentials
for more information.
The error mentioned comes from the line:
TextToSpeechClient textToSpeechClient = TextToSpeechClient.create();
This error appears because of the fact that on the android emulator I don't have access to the credentials that are set as environment variable in my OS..So I have to provide the credentials in another way.
In the case of other Google APIs, like Storage, I found out that this can be done like this:
// You can specify a credential file by providing a path to GoogleCredentials.
// Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
.createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
I managed to create the GoogleCredentials object with the contents of the json file, however the TextToSpeech client doesn't seem to provide a functionality similar to this:
StorageOptions.newBuilder().setCredentials(credentials).build()
So my question is....is there a way to provide the Credentials object to the TextToSpeech client?
Thanks
Currently, there is not a way to provide credentials to the TTS Client from this page.
Due to Security / Auth reasons, I believe the best suggested approach is to use Firebase Functions.
Get the Text
Call Firebase Functions
Have Firebase Functions call the TTS API
Return the results.
This way, no keys are leaked inside the application and you can use Firebase Auth.
Let me know if that helps!
Update:
Option 2: iOS Tutorial (should be adaptable to Android)
Get the Text
Call Firebase Functions
Have Firebase Functions return an OAuth2 Token
Use the token directly with the API

Youtube Data API with OAuth2.0 on Android

I'm trying to use the YouTubeData API with OAuth 2.0 authentication on Android, and i'm kind of struggling with it.
I've searched a lot online, but there's not much help for the Android implementation.
First of all, it's not clear to me what's the best way to obtain an OAuth token. In the doc they suggest that for Android is better to obtain it using the Google Play services lib. Is that true? if yes, it should be pretty trivial following this guide: https://developers.google.com/android/guides/http-auth.
But at this point i will have the token in a String object .. how should I use it with the YouTubeData API? Should I place it somewhere in the YouTube.Builder ?
YouTube youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException {
}
}).setApplicationName("AppName").build();
if yes, does anyone know where?
Searching on StackOverflow i've come across this question: What to do after getting Auth Token - Android Youtube API. Here Ibrahim Ulukaya says it's better to use GoogleAccountCredential. For what i've understood (Access to Google API - GoogleAccountCredential.usingOAuth2 vs GoogleAuthUtil.getToken()) the Android version of GoogleAccountCredential should use the GoogleAuthUtil provided from the Google Play services lib, so it could be pretty useful to simplify the process. I've looked at the sample project suggested from Ibrahim Ulukaya (https://github.com/youtube/yt-direct-lite-android) and i've implemented everything as he does. But it doesn't seem to work very well as i'm only obtaining this message in the logcat: "There was an IO error: com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission : null".
(Note that I've enabled all the required APIs on the Google Console, and created the Client ID for my app)
At this point i'm kind of lost.
Should I use directly the GoogleAuthUtil from the Google Play services lib? in this case once obtained the token as a String how can i use it with the YouTubeData APIs?
Or should I use the GoogleAccountCredential ? in this case someone knows how can I solve the "NeedPersmission : null" error?
---- EDIT:
details on what my app is trying to do: being this my first experience with this kind of APIs I started from the easy stuff: retrieve video information and then play those videos, without any user authentication. I managed to do that pretty easily, but for my app's purpose i need to access the user data, in particular users must be able to like and comment videos.
So I started implementing OAuth2, trying to do the same exact queries I was doing before (retrieve video info).
Wow. The documentation on this is super confusing. Full disclosure, I'm not an Android developer but I am a Java developer who has worked with Google apps and OAuth2.
Google Play or not Google Play? First off, Google Play Services will only be available on Android devices with Google Play Services installed (so not OUYA, Amazon devices, etc.). Google state that "the Google Play library will give you the best possible performance and experience.".
There are numerous discussions (e.g. here, here) from actual Android developers that list the various merits of Google Play verses other techniques. I would imagine that once you are able to get your application working using one method, then it should be an easy enough to change if you so desire.
Much of the example code about uses the Android AccountManager (Tasks and Calendars being favourite examples) so that is what I will show.
Your example code looks like it might be for a simple search, I would guess that many of the YouTube API interactions do not require OAuth2, in other code I've seen this empty HttpRequestInitializer implementation referred to as a no-op function. (e.g. GeolocationSearch.java).
It sounds like you want access to YouTube API operations that need account credentials. You can do something similar to this Android Calendar example (CalendarSampleActivity.java) except with YouTube, like the example answer from here.
// Google Accounts
credential = GoogleAccountCredential.usingOAuth2(this, YouTubeScopes.YOUTUBE, YouTubeScopes.YOUTUBE_READONLY);
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
// YouTube client
service =
new com.google.api.services.youtube.YouTube.Builder(transport, jsonFactory, credential)
.setApplicationName("Google-YouTubeAndroidSample/1.0").build();
I hope this helps.
In the initialize method of the HttpRequestInitializer you can set headers of the request. According to Googles documention for Oath2 for devices https://developers.google.com/identity/protocols/OAuth2ForDevices if you have an access token you should put it in the Authorization: Bearer HTTP header.
YouTube youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException {
request.put("Authorization", "Bearer " + yourAccessTokenString);
}
}).setApplicationName("AppName").build();
Remember the space after the Bearer in the authorization header value

ACRA formkey where to get it?

So I tried to follow instructions of https://github.com/ACRA/acra/wiki/BasicSetup but its too old or something.
Using my own gmail account I did import the csv file but there is no option "Create a LEGACY Form" in tools menu but only "Create form". If I create a form there are no fields of imported csv file (like I can see on screenshot in BasicSetup document) but it prompts to add fields manually using "Add item". And there is no any formkey around. The http link of form is looks like: https://docs.google.com/forms/d/1KNF_R4_Re0X0giFfEXwqXY50mpnFvQUvp0NLkKxyI/edit# or if I choose "view live form" it is https://docs.google.com/forms/d/1KNF_R4_Re0X0giFfEXwqXY50mpnFvQUvp0NLkKxyI/viewform As you can see there is no formkey included.
So the question is there I can find that fomkey now?
As the use of Google Docs is deprecated for ACRA I recommend you to use BugSense as your Back-End service:
1. Go to their site and sign in: http://www.bugsense.com/
2. Create a new project to monitor in BugSense site, as a result you will receive an API Key for this application.
3. Finally add this line to you Application class in you project:
#ReportsCrashes(formUri = "http://www.bugsense.com/api/acra?api_key=YOUR_API_KEY", formKey="")
You can also check this blog post I wrote on:
Crash Reports and Usage Monitoring
Google spreadsheets are not supported on ACRA. Use a third party provider like BugSense instead or write your own error collector.
I have tried ACRA with my custom domain which handled by google and at that time i could not found any option to create to
Create a LEGACY Form
then after i have tried with my personal gmail account and its works .
so i came to conclusion is that :
ACRA dose not support Third party domain even-though they provided
google .

Categories

Resources