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());
}
}
Related
An application is published on Play Store and it is using 'application data folder' for the backup-restore purpose using Drive API. Everything works fine. However, this API is about to be turned down on 6th December, 2019 according to Google's announcement. Therefore, in order to support existing users, I have been migrating to latest API according to migration guidlines and an official sample app.
I can successfully authenticate using the code (from the official link) below.
GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestScopes(new Scope(DriveScopes.DRIVE_APPDATA))
.build();
GoogleSignInClient client = GoogleSignIn.getClient(this, signInOptions);
// The result of the sign-in Intent is handled in onActivityResult.
startActivityForResult(client.getSignInIntent(), REQUEST_CODE_SIGN_IN);
I am also using correct scope - DriveScopes.DRIVE_APPDATA as mentioned in the official documentation.
I am also seeing correct values of 'email' and 'granted scopes' inside onActivityResult()
if (requestCode == REQUEST_CODE_SIGN_IN && resultCode == RESULT_OK) {
GoogleSignIn.getSignedInAccountFromIntent(data).addOnSuccessListener(new OnSuccessListener<GoogleSignInAccount>() {
#Override
public void onSuccess(GoogleSignInAccount googleSignInAccount) {
Log.e("TAG", "Email - " + googleSignInAccount.getEmail()); // prints correct value
Log.e("TAG", "Granted scopes - " + googleSignInAccount.getGrantedScopes()); // prints correct value
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(getActivity(), Collections.singleton(DriveScopes.DRIVE_APPDATA));
credential.setSelectedAccount(googleSignInAccount.getAccount());
Drive googleDriveService = new Drive.Builder(
AndroidHttp.newCompatibleTransport(),
new GsonFactory(),
credential)
.setApplicationName("App Name") // Changed it for now
.build();
mDriveServiceHelper = new DriveServiceHelper(googleDriveService);
queryFiles();
}
});
}
However, whenever I try to access a backup file in queryFiles() using the code (from the official link) below,
FileList files = driveService.files().list()
.setSpaces("appDataFolder")
.setFields("nextPageToken, files(id, name)")
.setPageSize(10)
.execute();
for (File file : files.getFiles()) {
System.out.printf("Found file: %s (%s)\n",
file.getName(), file.getId());
}
It throws the following error
{
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
Kindly help me fix the error. I believe that as everything is working fine with the published version, everything should be correct in terms of configuring on Google API console.
I probably can't find ALL threads with this problem but I can try to help in a few or so.
PRIMARY ANSWER
IF you're using ProGuard same as I am. ProGuard can cause this error to happen during query. I fixed it using the following.
# Fix OAuth Drive API failure for release builds
-keep class * extends com.google.api.client.json.GenericJson { *; }
-keep class com.google.api.services.drive.** { *; }
-keepclassmembers class * { #com.google.api.client.util.Key <fields>; }
SECONDARY ANSWER
Note that you DO NOT need to use keys/tokens using the Drive rest API with Android like you may find from other solutions (it may not hurt either, but it can). It doesn't match up here to what people talk about elsewhere (here they don't know what they're talking about).
See my notes here for further info: Google Drive via OAuth release version receives dailyLimitExceededUnreg
IF you have the problem however in debug build then you did not do everything correctly. My notes should get you on the right track.
If you need further help, I might assist because of how nuts it is.
EXAMPLE OF GETTING A FILE FROM DRIVE WITH THE NEW API USE
Just see from the following link
public Task<Pair<String, String>> readFile(String fileId)
https://github.com/gsuitedevs/android-samples/blob/master/drive/deprecation/app/src/main/java/com/google/android/gms/drive/sample/driveapimigration/DriveServiceHelper.java
The id comes from the query result where the id is part of that query info attached to that which is returned from the Drive query. The id is the file id for the file you want to retrieve. Pass that in to readFile and it gives you the file contents back that you can save locally to java.io.File eg fileOutputStream.write(contents.getBytes()); the contents of which is pair.second. You would then have your hopefully (because sometimes we have more work to do) identical java.io.File.
You can see a basic query if you need one in the the link sample as well but its missing some important info because depending on what you do you may need to check if trashed, get file size, modify time, md5, set order, etc. You may need to see https://developers.google.com/drive/api/v2/reference/files/list and https://developers.google.com/drive/api/v3/reference/files etc to figure that out. If enough files, there will be a paged requirement as well.
I know using Drive from code is a bit nuts (well, it is to me anyway lol) so hang in there =)
For Documentation purposes as a troubleshooting step:
Go to
https://console.developers.google.com/project/<project-id>/apiui/api
Or for Google Scripts:
https://script.google.com/home/usersettings
Replace with the ID of your application and check that the Google Drive API is turned on.
If it isn't - make sure to get a new token after turning it on if this is the case.
When doing a Geocoderequest in the Here API for Android I get the result FORBIDDEN for any search string.
Here is a snippet of the code (Kotlin) :
class GeoListner : ResultListener <MutableList<Location>>
{
override fun onCompleted(p0: MutableList<Location>?, p1: ErrorCode?) {
Log.d(this.javaClass.toString(),"Result code of search is ${p1?.name}")
}
}
fab_search.setOnClickListener { View ->
var currentPos = GeoCoordinate(49.2849,-123.1252)
val listner : ResultListener<MutableList<Location>> = GeoListner()
val request = GeocodeRequest("Granville").setSearchArea(currentPos,5000)
if (request.execute(listner) != ErrorCode.NONE)
{
}
}
This search area and string is picked from the HERE-API documentation for Here. Also i notice that the GeocodeRequest is deprecated, but the result for GeocodeRequest2 is the same error.
Anyone ?
Regards
Trond
Summary: Please ensure that you set the APP_ID and APP_CODE in the manifest file correctly.
For the background: Developers using HERE SDK with their app are required to register for a set of HERE credentials and to specify these credentials (App_Id and App_Code) in their app's Android manifest XML file. Failure to do so results in blocked access to certain features and degradation in the quality of other services.
To obtain these credentials visit the developer portal at https://developer.here.com/plans and register for a license. Once your project is created, you can generate these credentials on your Project Details page. If you already have a plan, you can also retrieve these credentials from your Project Details page.
Note: Credentials are unique to your account and your application's package namespace. Avoid reusing credentials across multiple applications.
I am getting com.ibm.watson.developer_cloud.service.exception.UnauthorizedException: Unauthorized: Access is denied due to invalid credentials error while i am using the right credentials. I am doing like this..
Imports :
import com.ibm.watson.developer_cloud.visual_recognition.v2_beta.VisualRecognition;
import com.ibm.watson.developer_cloud.visual_recognition.v2_beta.model.VisualClassification;
Code :
service = new VisualRecognition(VisualRecognition.VERSION_DATE_2015_12_02);
service.setUsernameAndPassword("GXXXXxxxxxxx", "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
File image = new File("src/test/resources/visual_recognition/car.png");
VisualClassification result = service.classify(image).execute();
Dependencies :
compile 'com.ibm.watson.developer_cloud:java-sdk:3.0.0-RC1'
Where on Bluemix the Visual Recognition credentials are like this
{
"credentials": {
"url": "https://gateway.watsonplatform.net/visual-recognition-beta/api",
"password": "GXXXXxxxxxxx",
"username": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
Please help me to solve the issue. Thanks in advance!
This may be an error in your question, rather than an error in your code, however please double check that you pass to setUsernameAndPassword method the parameters in the correct order (username, password) as specified in the API Reference. Looking at your code I see
service.setUsernameAndPassword("GXXXXxxxxxxx", "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
that is (password, username). I've just tried using the correct order and it works fine for me.
I'm trying to create Parse apps on the fly and use the keys while building my Android application. The API works great except for one point, it does not return the Client Key.
{
"appName": "my new app",
"dashboardURL": "https://www.parse.com/apps/my-new-app--30",
"applicationId": "oQqMyipkIgxYFXRROYTZsREfTcXp770awB1yMVrs",
"javascriptKey": "XAPZ7DoZHQIhMC8vPqN1m79wRIQyIXv7tmVIHmRs",
"windowsKey": "ZsyfFr0WtaQx6tsCokNSmTvjd05QCbCbMLzpChvP",
"webhookKey": "LyXnWJ3tRH56gK19KC1fjTvoUbdSUZoXhyO6khoT",
"restKey": "dzpdzYNkts2xZxPDVe7qC298Z20oIXhLJAPuY2Dw",
"masterKey": "0M2uUDZdKa1KYC1VBrmDaGK3chBaUMw0c2M4XXw1",
"clientPushEnabled": true,
"clientClassCreationEnabled": true,
"requireRevocableSessions": true,
"revokeSessionOnPasswordChange": true
}
And I need the client key as mentioned in the Android API:
Parse.initialize(this, "YOUR_APP_ID", "YOUR_CLIENT_KEY");
I have tried toggling the flags in vain.
What should I do inorder to access the Client Key?
Edit:
I'm talking about the Client Key which appears here: http://postimg.org/image/f76lj6xcr/
This was a minor bug in the Parse REST API. They fixed it within 48 hours after reporting.
I found how to send push notification to Android device using Django here (here is the code).
So adopted that and my code looks like this:
def sendAndroidPushNotification(registration_id, collapse_key, a, b) :
try:
auth = getNewAndroidAuthorizationToken() # this works I'm fetching new token so this is up to date (its length is 267 characters)
push_request = urllib2.Request("https://android.apis.google.com/c2dm/send")
data = urllib.urlencode({'data.testA' : a,
'data.testB' : b,
'collapse_key' : collapse_key,
'registration_id': registration_id
})
push_request.add_data( data )
push_request.add_header('Authorization', 'GoogleLogin auth=' + auth)
push_request.add_header('Content-Type', 'application/x-www-form-urlencoded')
push_request.add_header('Content-Length', len(data))
urllib2.build_opener().open(push_request)
except urllib2.HTTPError as e:
print 'got exception during push notification'
print 'Reason: "{0}" code: {1}'.format(e.reason, e.code)
pass
this give me error: "Reason: "Unauthorized" code: 401" (at some point it was 403). Version which uses httplib.HTTPSConnection instead of urllib2.Request has same problem.
It looks almost the same as code shown here so I'm totally confused. What I'm doing wrong?
Edit:
Just in case, here is how I fetch authorization token (it looks like that it works fine), maybe my parsing is wrong:
def getNewAndroidAuthorizationToken() :
request = urllib2.Request("https://www.google.com/accounts/ClientLogin")
data = urllib.urlencode({'accountType' : 'HOSTED_OR_GOOGLE',
'Email' : 'someaccount#gmail.com',
'Passwd' : 'asdjsdfa',
'service' : 'ac2dm',
'source' : 'com.mycompany.mypackage',})
request.add_data(data)
content = urllib2.build_opener().open(request)
lines = content.readlines()
for line in lines :
if line.find("Auth=")==0 :
return line[5:]
return
C2DM is deprecated. Developers are encouraged to switch to GCM, C2DM will be supported for a short time. Simple API instead of ClientLogin and oAuth2 which are not supported.
http://developer.android.com/guide/google/gcm/index.html