Search code examples
androidoauth-2.0google-drive-apigoogle-drive-android-api

Error while migrating to latest Google Drive API in Android - Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup


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.


Solution

  • 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 =)