I have use the code from this topic : Unable to get the subscription information from Google Play Android Developer API
I can get the refresh token from the uri
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=REDIRECT_URI&client_id=CLIENT_ID
I call getRefreshToken(token from URI) and the anwser is :
{
"access_token" : "ya29.1.AADtN_XSr_9GwIybDh0fT5kt487DGYEed2sTzugp_MDOLEJAiMOTY3o17HwnvA7BIgP6",
"token_type" : "Bearer",
"expires_in" : 3407
}
With this acces token I can get information about my google android developper account.
The problem is the access token expires after 1 hour and I can't regenerate it.
I try to call getAccessToken(token from uri) and the anwser is :
{
"error" : "invalid_grant"
}
I use this code on a google app engine server in JAVA.
If someone recode thus methode with com.google.api.client.auth.oauth2 can be awesome.
Default first response when you get the refresh token is:
{
"access_token" : "****",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "****"
}
Every next response returns:
{
"access_token" : "****",
"token_type" : "Bearer",
"expires_in" : 3600,
}
You need delete oAuth from google account or use "approval_prompt=force" in request for force take refresh token.
Related
i am trying to add a login with google to my android app. i installed nativescript-google-login ant did everything as i should and i redirected to the login window of google. but after i insert my details instead of getting the token and the info of the user i get this:
{
"provider": "google",
"code": 1
}
my google init looks like that:
google.GoogleLogin.init({
google: {
initialize: true,
serverClientId: "<client id of a web client for oauth 2.0>",
clientId: "<cient id for android>",
isRequestAuthCode: true
},
activity: application.android.foregroundActivity
})
what am i missing?
I want to get Auto renew subscription detail for that i can follow this official DOCUMENT:
In this document first step is Authorization. and i complete all steps and i get refresh_token AND access_token.
Now main part is there is one API to get renew subscription detail:
API: https://www.googleapis.com/androidpublisher/v3/applications/packageName/purchases/products/productId/tokens/token
In this api there is three data required:
PackageName - Which i add from AndroidManifest.xml
SubscriptionId : Where to i get Subscription ID?
Token : Which i can get from Authorization steps.
Main problem is Where to i get subscription ID. Is Product Id is Subscription ID or What??
If SubscriptionId is ProductId then my API not working. API response is:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid Value"
}
],
"code": 400,
"message": "Invalid Value"
}
}
Anyone have solution? or information about Subscription ID?
subscription ID is another term for SKU. You may also see it listed as product ID. They are the ID that you entered in the Play Developer Console when you first listed your products
https://play.google.com >> [choose an app] >> Store presence >> In-app products >> subscriptions >> Name & ID
The ID that you see there is the subscription ID.
Another way to find your SKU (aka subscription ID, product ID), is through SkuDetails#getSku() on the list of SkuDetails you get from querySkuDetailsAsync(params) in your Android client.
update with javascript/typescript snippet
async function getSubscriptionPurchaseFromPlay(sku: string, purchaseToken: string) {
const params = {
packageName: PACKAGE_NAME,
subscriptionId: sku,
token: purchaseToken
};
const response = await playDeveloperApi.purchases.subscriptions.get(params);
console.log("getSubsPurchaseFromPlay response:: ", response);
return response.data;
}
You must use the SKU in all places where you are requested to provide productId or subscriptionId. For example:
https://www.googleapis.com/androidpublisher/v3/applications/packageName/purchases/products/productId/tokens/token
https://www.googleapis.com/androidpublisher/v3/applications/packageName/purchases/subscriptions/subscriptionId/tokens/token
I'm trying to use the Google Cloud Translation API in my application but whenever I try to translate something it comes up with this missing valid API error.
I've done the quickstart steps and that didn't work.
I've tried the steps in the client library authentication and that hasn't worked either.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: herrsa1.bit.translator, PID: 16598
com.google.cloud.translate.TranslateException: The request is missing a valid API key.
at com.google.cloud.translate.spi.v2.HttpTranslateRpc.translate(HttpTranslateRpc.java:61)
.. 18 more
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [{
"domain" : "global",
"message" : "The request is missing a valid API key.",
"reason" : "forbidden"
}],
"message" : "The request is missing a valid API key.",
"status" : "PERMISSION_DENIED"
}
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
... 4 more
at com.google.cloud.translate.spi.v2.HttpTranslateRpc.translate(HttpTranslateRpc.java:130)
... 19 more
If you are using client library and you have already downloaded your service account json file, try doing this:
// Instantiates a client
const translate = new Translate({
projectId: 'your project id', //eg my-proj-0o0o0o0o'
keyFilename: 'path of your service acount json file' //eg my-proj-0fwewexyz.json
});
instead of this:
// Instantiates a client
const translate = new Translate({projectId});
This way you need only your the service acount json file and the specific API enabled
The error on API key means you didn't create or use the key properly. You need to do the following for the key to work:
Create a service account
Create a key for above service account
Download the key to a location, for example, a local path
Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the file path of the key, refer to samples in Quickstart tutorial
I'd reccomend doing #1 & #2 in GCP Console, and handling #3 & #4 in Cloud Shell.
The key your using does not have the permission to use Translate APIs.
To fix this :
Go to Google Cloud Platform console
Chose your project from the drop down menu in the top bar
Go to API & Services > Library
Search for Cloud Translation API and click on it
Enable it
Go to API & Services > Credentials
Select the key you are using in your Android App
From the menu called Restrict key, choose Cloud Translation API
Save your edit
Now the APIs will work properly.
I also tried to execute this sample program.
I followed the same instruction. But when I executing I got same error(The request is missing a valid API key).
I changed a line in the sample program.
Instead of
Translate translate = TranslateOptions.getDefaultInstance().getService();
I added
Translate translate = TranslateOptions
.newBuilder()
.setCredentials(
ServiceAccountCredentials
.fromStream(new FileInputStream(
"YourCredentialFilePath.json")))
.build().getService();
Now it is working.
Sample code after fix.
// Imports the Google Cloud client library
import java.io.FileInputStream;
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.translate.Translate;
import com.google.cloud.translate.Translate.TranslateOption;
import com.google.cloud.translate.TranslateOptions;
import com.google.cloud.translate.Translation;
public class QuickstartSample {
public static void main(String... args) throws Exception {
//Instantiates a client
//Removed next line
//Translate translate = TranslateOptions.getDefaultInstance().getService();
//Added this line
Translate translate = TranslateOptions
.newBuilder()
.setCredentials(
ServiceAccountCredentials
.fromStream(new FileInputStream(
"YourCredentialFilePath.json")))
.build().getService();
//The text to translate
String text = "Hello, world!";
//Translates some text into Russian
Translation translation =
translate.translate(
text,
TranslateOption.sourceLanguage("en"),
TranslateOption.targetLanguage("ru"));
System.out.printf("Text: %s%n", text);
System.out.printf("Translation: %s%n", translation.getTranslatedText());
}
}
I'm using google REST Api to retrieve list of spreadsheets.
Everything works when it is accessed by my account.
But when I try to use foreign account, I'm getting this error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden {
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "The caller does not have permission",
"reason" : "forbidden"
} ],
"message" : "The caller does not have permission",
"status" : "PERMISSION_DENIED"
}
It says I have no access to my google script, but the script is set as visible and shared for anyone.
Code:
private Object getDataFromApi(ExecutionRequest request)
throws IOException
{
if (BuildConfig.DEBUG) {
request.setDevMode(true); // it will take saved version of script and not the published one
}
// Make the request.
Operation op =
mService.scripts().run(SCRIPT_ID, request).execute();
Change the SCOPE from SheetsScopes.SPREADSHEETS_READONLY to SheetsScopes.SPREADSHEETS.
private static final List SCOPES = Arrays.asList(SheetsScopes.SPREADSHEETS);
I found the problem was in code:
if (BuildConfig.DEBUG) {
request.setDevMode(true); // it will take saved version of script and not the published one
}
It looks like it alway force to access saved version and not the published. Then the foreign account had no access to saved version and returns error 403.
When I disable this dev mode or install release version, then everything is ok.
I refered google play android api to check the purchase and consumption status of an in-app item.
For some orders, I can get right result,but some return the error as below:
error: {
errors: [
{
domain: "global",
reason: "purchaseTokenNotFound",
message: "The purchase token was not found.",
locationType: "parameter",
location: "token"
}
],
code: 404,
message: "The purchase token was not found."
}
Purchase token is provided by google, does it can be faked?
I found if I cancel the google order, then check the purchase status,it will return the purchase token was not found. if not, i will get the right purchase status.
Hope somebody can help.
If you are selling the same INAPP product to the same user muliple times within a short period, then it's very likely that all access tokens except the last purchase will return a 404 code.
For example:
john#example.com went to your app and purchased com.example.test.product a few times, you will probaly notice within your records (or Google Wallet Merchant account) that it's the same user buying the product.
When you go to check the last purchase from this user, then the following is likely to appear
{
kind: "androidpublisher#inappPurchase",
purchaseTime: "1409823171827",
purchaseState: "0",
consumptionState: "1",
developerPayload: "My Product | Ref | 1409823162466"
}
and yet if you were to check his previous tokens, then it's very likely that his purchases will return 404!
I had read somewhere (can't remember where) that the purchase token created for each purchase is basically based on the inapp product and google user. Therefore, it's very likely that each purchase will "destroy" any previous purchase token created for the same user.
Hope this explanation helps. I am constantly having this problem everyday when my server is attempting to connect to the Google API and check the transactions. Perhaps one day somebody will read this and provide a solution :)
The documents are misleading. You don't need to use this API to verify purchases.
Mobile app have INAPP_PURCHASE_DATA and INAPP_DATA_SIGNATURE from getBuyIntent method.
You can verify the purchase with the signature and your public key.
https://developer.android.com/google/play/billing/billing_reference.html#getBuyIntent
You can find the public key on Google Play Developer Console -> YOUR_APP -> service and API
package main
import (
"crypto"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
)
//replace const below with your own.
const (
pubKeyPEM=`-----BEGIN PUBLIC KEY-----
Some thing like this
-----END PUBLIC KEY-----`
data = `purchase data from getBuyIntent API`
sign = `purchase data signature from getBuyIntent API`
)
func Panic(err error) {
if err != nil {
panic(err)
}
}
func main() {
PEMBlock, _ := pem.Decode([]byte(pubKeyPEM))
if PEMBlock == nil {
Panic(fmt.Errorf("Could not parse Public Key PEM"))
}
if PEMBlock.Type != "PUBLIC KEY" {
Panic(fmt.Errorf("Found wrong key type"))
}
pubkey, err := x509.ParsePKIXPublicKey(PEMBlock.Bytes)
if err != nil {
Panic(err)
}
// compute the sha1
h := sha1.New()
h.Write([]byte(data))
// decode b64 signature
signature, err := base64.StdEncoding.DecodeString(sign)
Panic(err)
// Verify
err = rsa.VerifyPKCS1v15(pubkey.(*rsa.PublicKey), crypto.SHA1, h.Sum(nil), signature)
Panic(err)
// It verified!
fmt.Println("OK")
}