browser-samples
browser-samples copied to clipboard
Browser sample quickstart is obsolete
Summary
The Google Drive quickstart documentation is not working for some reason and I can't figure out why. This is the official doc page and this is the github file.
Back in 2024 I copied and ran the same quickstart code and it worked, but for some reason it's not working anymore, giving the following error:
API discovery response missing required fields.
gapix.client.GapiClientError: API discovery response missing required fields.
at new XA (https://apis.google.com/_/scs/abc-static/_/js/k=gapi.lb.pt_BR.ATNbtiFo1ho.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo_1YLh20Lb4BdBxVY5iwPfQkmf_Og/cb=gapi.loaded_0?le=scs:656:159)
at c (https://apis.google.com/_/scs/abc-static/_/js/k=gapi.lb.pt_BR.ATNbtiFo1ho.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo_1YLh20Lb4BdBxVY5iwPfQkmf_Og/cb=gapi.loaded_0?le=scs:708:48)
at e.Cr (https://apis.google.com/_/scs/abc-static/_/js/k=gapi.lb.pt_BR.ATNbtiFo1ho.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo_1YLh20Lb4BdBxVY5iwPfQkmf_Og/cb=gapi.loaded_0?le=scs:176:25)
at Sk (https://apis.google.com/_/scs/abc-static/_/js/k=gapi.lb.pt_BR.ATNbtiFo1ho.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo_1YLh20Lb4BdBxVY5iwPfQkmf_Og/cb=gapi.loaded_0?le=scs:179:59)
at Ok (https://apis.google.com/_/scs/abc-static/_/js/k=gapi.lb.pt_BR.ATNbtiFo1ho.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo_1YLh20Lb4BdBxVY5iwPfQkmf_Og/cb=gapi.loaded_0?le=scs:178:368)
at _.xk.nz (https://apis.google.com/_/scs/abc-static/_/js/k=gapi.lb.pt_BR.ATNbtiFo1ho.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo_1YLh20Lb4BdBxVY5iwPfQkmf_Og/cb=gapi.loaded_0?le=scs:178:238)
at jk (https://apis.google.com/_/scs/abc-static/_/js/k=gapi.lb.pt_BR.ATNbtiFo1ho.O/m=client/rt=j/sv=1/d=1/ed=1/rs=AHpOoo_1YLh20Lb4BdBxVY5iwPfQkmf_Og/cb=gapi.loaded_0?le=scs:169:116)
Expected behaviour
Authenticate and show metadata for first 10 files.
Actual behaviour
is this repo dead?
@jpoehnelt
Not sure what would be causing that. The sample is fairly because and almost all of the code is related to the oauth token.
Can you share the code you used?
// what does your code look like here?
gapi.client.drive.******
Thank you for answering @jpoehnelt , means a lot!
Yes I use create, list and get
gapi.client.drive.files.list({})
gapi.client.drive.files.create({})
gapi.client.drive.files.get({})
But the error happens before, when its loading gapi. I didn't post code before because I literally tried running the exact code thats on the docs, no changes whatsoever, and the same error happens, at the same call.
This is how my code looks:
<script type="text/javascript">
const CLIENT_ID = '----------CENSORED----------';
const GAPIK = '----------CENSORED----------';
const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';
const SCOPES = 'https://www.googleapis.com/auth/drive.appdata https://www.googleapis.com/auth/drive.appfolder';
let tokenClient;
let gapiInited = false;
let gisInited = false;
let firstLoad = true;
let loaded = false;
const authorizeEl = document.getElementById('authorize_button');
const loginLoadingEl = document.getElementById('login_loading');
const loginConfirmEl = document.getElementById('login_confirmation');
const startBtn = window.document.getElementById('confirm-btn');
const elementToObserve = window.document.getElementById('gdrive_userdata');
const observer = new MutationObserver(userDataChanged);
observer.observe(elementToObserve, {characterData: false, childList: true, attributes: false});
authorizeEl.style.visibility = 'hidden';
function gapiLoaded() {
gapi.load('client', initializeGapiClient);
}
// this is where it breaks if I'm not mistaken
async function initializeGapiClient() {
await gapi.client.init({
apiKey: GAPIK,
discoveryDocs: [DISCOVERY_DOC],
});
gapiInited = true;
maybeEnableButtons();
}
function gisLoaded() {
let redirectUri = 'https://diguifi.itch.io/tiny-land';
if (window.location.href.includes('localhost')) {
redirectUri = window.location.href;
}
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: CLIENT_ID,
scope: SCOPES,
callback: redirectUri,
});
gisInited = true;
maybeEnableButtons();
}
function maybeEnableButtons() {
if (gapiInited && gisInited) {
authorizeEl.style.visibility = 'visible';
}
}
// -----Every method bellow can be ignored but I'm leaving here for the sake of curiosity-----
function handleAuthClick() {
tokenClient.callback = async (resp) => {
if (resp.error !== undefined) {
throw (resp);
}
loginLoadingEl.style.display = 'block';
startBtn.disabled = true;
authorizeEl.style.display = 'none';
await loadData();
};
if (gapi.client.getToken() === null) {
tokenClient.requestAccessToken({prompt: 'consent'});
} else {
tokenClient.requestAccessToken({prompt: ''});
}
}
function handleSignoutClick() {
const token = gapi.client.getToken();
if (token !== null) {
google.accounts.oauth2.revoke(token.access_token);
gapi.client.setToken('');
authorizeEl.style.display = 'block';
loginConfirmEl.style.display = 'none';
}
}
async function loadData() {
try {
const response = await getAppDataFile()
let fileId = ''
if (response.files.length == 0) {
const createdFile = await createAppDataFile()
await saveAppData(createdFile.id, {data:"0"})
fileId = createdFile.id
} else {
fileId = response.files[0].id
}
const file = await getAppDataFileContent(fileId)
if (file) {
loaded = true
loginConfirmEl.style.display = 'block';
loginLoadingEl.style.display = 'none';
startBtn.disabled = false;
document.getElementById('gdrive_userdata').innerHTML = file.body;
document.getElementById('gdrive_fileid').innerHTML = fileId;
} else {
loginConfirmEl.innerHTML = 'Error loading data'
}
} catch (err) {
return;
}
}
async function getAppDataFile() {
const result = await gapi.client.drive.files.list({
q: 'name="tinydata.json"',
spaces: 'appDataFolder',
fields: 'files(id)'
})
return JSON.parse(result.body)
}
async function createAppDataFile() {
const result = await gapi.client.drive.files
.create({
resource: {
name: 'tinydata.json',
parents: ['appDataFolder']
},
fields: 'id'
});
return JSON.parse(result.body)
}
async function getAppDataFileContent(fileId) {
return await gapi.client.drive.files
.get({
fileId: fileId,
alt: 'media'
});
}
async function saveAppData(fileId, data) {
try { data = JSON.parse(data) } catch { }
return await gapi.client.request({
path: '/upload/drive/v3/files/' + fileId,
method: 'PATCH',
params: {
uploadType: 'media'
},
body: JSON.stringify(data)
});
}
async function userDataChanged() {
if (loaded && firstLoad) {
firstLoad = false;
return;
}
const newData = document.getElementById('gdrive_userdata').innerHTML
const fileId = document.getElementById('gdrive_fileid').innerHTML
if (newData && fileId) {
const result = await saveAppData(fileId, newData)
}
}
// here is where gis and gapi are loaded just like the docs, everything is like the docs except that I'm not listing gdrive folders, I'm saving data to the users gdrive for my app
</script>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>
@jpoehnelt I'm experiencing the exact same issue. The sample used to work fine before, but now it throws the following error:
API discovery response missing required fields.
The error occurs right after gapi.client.init, with no changes to the original code from the documentation. It seems like the Drive discovery endpoint is no longer returning the expected fields. Possibly something changed in the API or the gapi scripts that broke the integration.
my small game is simply not working because of this, for the last 7 months, thats insane
@sqrrrl please help, anyone! Theres more people with this problem: #209
bro
PLEASE