EddyVerbruggen / cordova-plugin-googleplus

:heavy_plus_sign: Cordova plugin to login with Google Sign-In on iOS and Android
567 stars 630 forks source link

Invalid credentials - youtube data api upload #344

Open PirateNick opened 7 years ago

PirateNick commented 7 years ago

Hello random stranges!

I've been struggling to get the puppy running for a while, so I've finally decided to give it a shot here :)

I'm creating a cordova (ionic/angular) hybrid video uploading app. Because I don't have money for running server, I was thinking about using youtube for video database, and firebase for storing the uploaded video information.

I integrated firebase using the Web JS files and they work flawlessly. Really I didn't even knew the possibilities with cordova, this is awesome. I first used authentication on firebase with google pop up, which, on local browser on laptop, works perfectly.

So as the happy little boy I was, I installed the app on my android phone to give it a go, you know, you never know what can go wrong. Turns out everything went wrong. Firebase google auth with popup is not supported.

Back to square one. I stumbled upon this plugin, integrated it into my project, and managed to get an Id token from loging in (after 2 hours of why the hell do I keep getting 12501 errors).

Now, my youtube upload script requires a access token, not a id token. So what I did:

Create web client id and use it to log into google plus:

 window.plugins.googleplus.login(
        {
            'scopes': 'https://www.googleapis.com/auth/youtube.upload',
            'webClientId': 'lotsofnumberswooooo.apps.googleusercontent.com'
        },
        function (obj) {
            onLoginCallback(obj);
        },
        function (msg) {
            alert('I am a noob at cordova because: ' + msg);
        }
    );

which gives me an Id token, yey!

Now, I somehow figured out you can log in using that id token into firebase like this:

 var credential = firebase.auth.GoogleAuthProvider.credential(loginData.idToken);
                firebase.auth().signInWithCredential
                 (credential).then(function(result) {
                    var str = JSON.stringify(result, null, "\t");
                    var accessToken = JSON.parse(str).stsTokenManager.accessToken;
                    $scope.accessToken = accessToken;
                    alert('access token: ' + accessToken);
                    callback();

                }).catch(function(error) {
                    puursApp.showPopup(error.message);
                });

And I even get all my google info! and, somewhere buried in there, the access token (Yea I have no idea why I had to stringify it and parse it back but that was the only way stsTokenManager was not undefined)!

Only to push the access token into my youtube upload script and get the error:

Invalid credentials:


{
  "error": {
    "code": 401, 
    "message": "Invalid Credentials", 
    "errors": [
      {
        "locationType": "header", 
        "domain": "global", 
        "message": "Invalid Credentials", 
        "reason": "authError", 
        "location": "Authorization"
      }
    ]
  }
}

Dreams crushed, and all hope is lost :(

Any idea where I could start to find the problem? I enabled google data api in my google project, added the web client id to my firebase whitelist (thats only to log in with the id token i think) and added the youtube upload scope to my scopes as you can see above.

Yes I also configured the release keystore sha1 which I signed the apk with in my android client id.

I can't give you money or fame, but non profit organization and me will be very grateful !

Nick

signalpoint commented 7 years ago

@NickPeelman I had a similar problem with the Invalid Credentials error maybe 2-3 months ago, and eventually gave up. It's nice (and crappy) to see someone else reporting this (as I should have), so thank you for starting this issue/discussion.

For me, Firebase wasn't involved at the time in regards to YouTube upload within a Cordova app. On a separate project though I was using push notifications and was getting some weird issues, but then I used Firebase with the project and push notifications started working again.

It is interesting to see that you're involving Firebase here, which gives me some hope in regards to YouTube upload within cordova. I'm forced to confront this problem again for the future of an app right now, so I will be fighting the same battle and will report findings here.

PirateNick commented 7 years ago

Hello signalpoint,

I did solve the issue, somewhat. The problem was that I was trying to use the accesstoken from firebase. Which is not the same as a google access token!!

U see, I logged in with credentials, that doesn't give me the accesstoken. I had to use GAPI (click here) to exchange my client id and api id for the right access token. Only then I was allowed to upload videos :)

So, basicly the app goes like:

Log in with external Google plugin, Use that data to log in to Firebase, Use that data to get access token from google, use that data to upload to youtube.

One hell of a ride, if you have any questions, post ahead :)

signalpoint commented 7 years ago

@NickPeelman Thank you for the follow up, I had luckily solved it somewhat as well. My problem was using an older version of the Google API when trying to get the access token. But then using this snippet after logging in, the access token worked perfectly for me:

// Exchange the authorization code for an access token.
$.post('https://www.googleapis.com/oauth2/v4/token', {
  client_id: '...',
  client_secret: '...',
  grant_type: 'authorization_code',
  code: loginResult.serverAuthCode
}).done(function(data) {
  console.log('oauth2 v4 token', data);
  var accessToken = data.access_token;
}).fail(function(response) {
  console.log('access token fail', response);
});

Since I am using server side user management, I am able to leave Firebase out of the equation for now (until I need push notifications). My steps are as follows:

  1. Log in with external Google plugin,
  2. Use that data to get access token from google,
  3. use that data to upload to youtube

Side note, I also had to set None on the Key restrictions for the Android API Key in my Google API Console, otherwise I was not able to successfully poll for the processing status of the video with YouTube. Another day, another problem. But all is well for now, cheers!

I'd go ahead and close this issue, as I think we've worked out our separate but related problems. Good luck and happy coding all.