cannot get folderId that i just created on google drive
Do not mix DriveId with ResourceId. Both look like strings, but DriveId is different from ResourceId. See SO 21800257. Also, ResourceId is not immediately available, see SO 22874657.
DriveId usually looks like:
"DriveId:CAESHDBCMW1RVblahblahblahblahMYjAUgssy8yYFRTTNKRU55"
whereas ResourceId is more like:
"UW2ablahblaghblahNy00Ums0B1mQ"
UPDATE:
Since so many developers fight this issue, I'll try to elaborate as deep as my knowledge allows me to.
Google Drive Google Play Svcs YourApp
(up in the cloud) (on your device) (on your device)
+--------------------+ +--------------+ +--------------+
| 'id' (RESTful API) | - - -> ResourceId - - - -> ResourceId |
+--------------------+ | DriveId - - - -> DriveId |
+--------------+ +--------------+
What I'm trying to convey with the artistic expression above is:
- When you create a drive object (folder/file) on your device, GooPlaySvcs will give you the DriveId
- You can use this DriveId for local communication with GooPlaySvcs, you can cache it, etc.
- Per Daniel's comment in SO 21800257 (link above), do not rely on DriveId to be a constant string,
it supposedly changes upon the object being committed. Use DriveId.equals() (I did not test that) - Anytime you step outside of the local device (Drive web interface, other apps, YourApp on a different
device), you need to use ResourceId, which is the only unique ID on the Drive (up in the cloud :-). - The ResourceId is available to your AFTER GooPlaySvcs commit the object to the Drive. There are
ways to force it, but it is a different story (search for requestSync()). If you decide to grab the ResourceId and use it for RESTfull calls (delete/trash), be aware
of the fact that Google Play Services propagates its changes on a schedule you don't have control
over (so it seems, see the requestSync() issue again), and your REST/GDAA fight can cause damage
to your data. GDAA(GooPlayServices) may not be aware of your REST changes for a while. You have
to manage the synchronization yourself. I admit I failed miserably when I tried.Good Luck
How to get Folder ID while creating a new folder in Google Drive using API
When you insert a file or create a directory you use Files: insert If successful, this method returns a Files resource in the response body.
If you check the return of your insert you will find id which is the id of the file or directory that you just created. You can then use this as the parent for your new directory.
Code directly from the documentation:
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, mimeType);
request.Upload();
File file = request.ResponseBody;
Console.WriteLine("File ID: " + file.Id);
How to get the FolderID from Google Drive folders using Chilkat DLL
I managed a way by performing iterative requests.
Don't know if this is the correct way, but it works...
Here's the code, now using the FolderPath with format /folder1/folder2/folderN
Private Function GetFolderID(ByVal FolderPath As String) As String
Dim Rest As New Chilkat.Rest
' Connect to Google APIs server
Dim Connected As Boolean = Rest.Connect("www.googleapis.com", 443, True, True)
If Not Connected Then
Return "Error attempting to connect: " & Rest.ConnectFailReason
Exit Function
End If
' Provide the Access token
Dim GAuth As New Chilkat.AuthGoogle
GAuth.AccessToken = M_AccessToken
Rest.SetAuthGoogle(GAuth)
' Instance to JSON object
Dim JSON As New Chilkat.JsonObject
JSON.EmitCompact = False
' Parse the provided path and split to array
Dim ParseFolder As String = Strings.Right(FolderPath, Len(FolderPath) - 1)
Dim Folders As String() = Split(ParseFolder, "/")
' Get the root folder that is in the Google Drive folders structure
Rest.AddQueryParam("q", "'root' in parents and name='" & Folders(0) & "'")
Dim Response As String = Rest.FullRequestNoBody("GET", "/drive/v3/files")
If Not Rest.LastMethodSuccess Then
Return Rest.LastErrorText
Exit Function
End If
JSON.Load(Response)
'Iterate on the folders to get the last folder's id
Rest.ClearAllQueryParams()
For i = 1 To Folders.Length - 1
Dim sbQuery As New Chilkat.StringBuilder
sbQuery.Append("name = '" & Folders(i) & "' and '")
sbQuery.Append(JSON.StringOf("files[0].id"))
sbQuery.Append("' in parents")
Rest.AddQueryParamSb("q", sbQuery)
Response = Rest.FullRequestNoBody("GET", "/drive/v3/files")
If Not Rest.LastMethodSuccess Then
Return Rest.LastErrorText
Exit Function
End If
JSON.Load(Response)
Next
' Get the folder id
Return JSON.StringOf("files[0].id")
End Function
unable to access folder just created Google Drive
You can't depend on global variables to save state between calls. Each time you call a script a new script instance is spawned. Each one will maintain its own state.
For example:
google.script.run.createSharedSubFolder(...) --> Script Instance 1..var childFolderIdA=folderId;
google.script.run.saveFile(...) --> Script Instance 2..var childFolderIdA=null;
You can save the the folderId to the users property store:
PropertiesService.getUserProperties().setProperty("childFolderId", childFolderId);
You can retrieve the folder Id:
var folderId = PropertiesService.getUserProperties().getProperty("childFolderId");
Your code with this change:
function doGet() {
return HtmlService.createHtmlOutputFromFile('multifile').setTitle('test – multi upload').setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function test(parent,child){
createSharedSubFolder(parent,child);
}
function createSharedSubFolder(parent,child) { // folder names as string parameters
var folders = DriveApp.getFolders();
var exist = false
while (folders.hasNext()) {
var folder = folders.next();
if(folder.getName()==parent){exist = true ; var folderId = folder.getId(); break};// find the existing parent folder
}
if(exist){ //parent folder exists
var child = DriveApp.getFolderById(folderId).createFolder(child).setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
var childFolderId = child.getId();
PropertiesService.getUserProperties().setProperty("childFolderId", childFolderId);
}else{
var childFolder = DriveApp.createFolder(parent).createFolder(child); //create parent and child folders
childFolder.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
}
}
function saveFile(data,name,folderName) {
var contentType = data.substring(5,data.indexOf(';'));
var file = Utilities.newBlob(Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)), contentType, name); //does the uploading of the files
var childFolderId = PropertiesService.getUserProperties().getProperty("childFolderId");
DriveApp.getFolderById(childFolderId).createFile(file);
}
Find or create folder in Google Drive
Modification points:
- At the method of "Files: list" of Drive API v3, the GET method is used. So the request body of
form
is not used in the request. In this case, the search query ofq
is required to be used as the query parameter.
When above points are reflected to your script, it becomes as follows.
From:
var metadata = {
q: "mimeType = 'application/vnd.google-apps.folder' and name = 'TESTSCREENITYFOLDER'"
};
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
// Upload to Drive
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/drive/v3/files');
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.responseType = 'json';
xhr.onload = () => {
var folderId = xhr.response.files.data.id;
// Open folder in Drive in a new tab
chrome.tabs.create({
url: "https://drive.google.com/drive/u/0/folders/"+folderId
});
};
xhr.send(form);
To:
const url = 'https://www.googleapis.com/drive/v3/files?q=' + encodeURIComponent("mimeType = 'application/vnd.google-apps.folder' and name = 'TESTSCREENITYFOLDER'");
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.responseType = 'json';
xhr.onload = () => {
var res = xhr.response.files;
if (res.length > 0) {
var folderId = res[0].id;
console.log(folderId); // You can check the retrieved folder ID here.
// Open folder in Drive in a new tab
chrome.tabs.create({
url: "https://drive.google.com/drive/u/0/folders/"+folderId
});
} else {
console.log("The folder of 'TESTSCREENITYFOLDER' was not found.");
}
};
xhr.send();
Note:
- In this modification, it supposes that your
token
can be used for using the method of "Files: list". Please be careful this. - When there are several folders with the same folder names in your Google Drive, you can check with
var res = xhr.response.files
.
Reference:
- Files: list of Drive API v3
Google drive API - Getting name of folder from id
In your script, how about the following modification?
Modified script:
async function DlImgFromFolder(auth, folderId) {
const drive = google.drive({ version: "v3", auth });
const res = await drive.files
.get({ fileId: folderId })
.catch((err) => console.log(err.errors));
if (!res) return;
const folderName = res.data.name;
var query =
"'" +
folderId +
"' in parents and mimeType contains 'image/' and trashed = false";
drive.files.list(
{
q: query,
fields: "files(id, name)",
},
function (error, response) {
if (error) {
return console.log("ERROR", error);
}
response.data.files.forEach(function (item) {
var file = fs.createWriteStream("./" + folderName + "/" + item.name);
file.on("finish", function () {
console.log("downloaded", item.name);
});
// Download file
drive.files.get(
{
fileId: item.id,
alt: "media",
},
{
responseType: "stream",
},
function (err, response) {
if (err) return "";
response.data
.on("error", (err) => {})
.on("end", () => {})
.pipe(file);
}
);
});
}
);
}
- In this modification, the folder name is retrieved from the inputted folder ID using "Files: get" method.
Note:
- In this case, when your local PC has no folder of
folderName
, an error occurs. Please be careful about this.
Reference:
- Files: get
Service account created folders do not apear in google drive web application
What you need to remember is that a Service account is not you. A service account is a dummy user. It has its own google drive account. when you upload the files to the service accounts drive account they are only accessible by that account as it is the owner of it.
Share a drive
You could create a drive on your google drive account share that directory with the service accounts email address. Then the service account can upload to that drive (parent) id. The files will then apear in that drive make sure that you have the service account grant your google account permissions on the file.
Share the file
If you want to leave the file on the Service account drive account then you can simply have the service account share the file with you then it will popup as a shared file in your google drive account.
sharing
Open the Google drive website right click the directory or file you want to share and click share. Take the service accounts email address and share it with that. It will then have access to that directory.
Related Topics
Better Way to Format Currency Input Edittext
Phonegap - Add a Splash Screen for Android App
Windowsoftinputmode="Adjustresize" Not Working with Translucent Action/Navbar
How to Draw Free Hand Polygon in Google Map V2 in Android
How to Keep/Exclude a Particular Package Path When Using Proguard
HTML List Tag Not Working in Android Textview. What How to Do
Transfer Data Between iOS and Android via Bluetooth
Non-Scrollable Listview Inside Scrollview
Installation App Blocked by Play Protect
Android Dex Gives a Bufferoverflowexception When Building
How to Set Layout_Gravity Programmatically
How to Start Service-Only Android App
Why Is My Button Text Forced to All Caps on Lollipop
Referencing a String in a String Array Resource with Xml
Listview with Clickable/Editable Widget