How to get Google Drive file ID - google-drive-api

I've created a file to Drive root using Google Drive Android API. How can I get this file ID to share it using Google Client Library?
Getting DriveFileResult in ResultCallback<DriveFileResult> callback returns Null:
String fileId = result.getDriveFile().getDriveId().getResourceId();

The callback is to the file being created locally. The DriveId will only have a resourceId when the file is synced to the server. Until then getResourceId will return null.
https://developer.android.com/reference/com/google/android/gms/drive/DriveId.html#getResourceId()
Use CompletionEvents to be notified when syncing with the server has occurred. Then calling getResourceId() should deliver what you are expecting.

this code might help to identify the id for a file present in the google drive.
public static void main(String[] args) throws IOException {
// Build a new authorized API client service.
Drive service = getDriveService();
// Print the names and IDs for up to 10 files.
FileList result = service.files().list()
.setMaxResults(10)
.execute();
List<File> files = result.getItems();
if (files == null || files.size() == 0) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getTitle(), file.getId());
}
}
}

Related

How to download a pdf file from IPFS usng ipfs core api in .net?

Recently i am trying to upload a file to IPFS and download/retrieve it using ipfs core api. And for this purpose a use .net library ipfs(c#) library. its works fine for a txt file but when i uploaded a pdf file and tries to download it gives me some kind of string.i thought that that string maybe my pdf file all content but that string proves me wrong. when i tries to compare my original pdf file string with (current string) that is totally diffferent..
my pdf file hash : QmWPCRv8jBfr9sDjKuB5sxpVzXhMycZzwqxifrZZdQ6K9o
and my c# code the get this(api) ==>
static void Main(string[] args)
{
var ipfs = new IpfsClient();
const string filename = "QmWPCRv8jBfr9sDjKuB5sxpVzXhMycZzwqxifrZZdQ6K9o";
var text = ipfs.FileSystem.ReadAllTextAsync(filename).Result;
}
my question is whtat i have done wrong and i have done some wrong then how can i get a pdf file ?? how ??
First of all please check if you can access to the file from live environment:
e.g.
https://ipfs.infura.io/ipfs/QmNtg1uDy1A71udMa2ipTfKghArRQFspfFkncunamW29SA
https://ipfs.io/ipfs/
if the file was uploaded correctly you can IpfsClient package to do this action:
Define property that references on ipfs env (e.g. via infura)
_ipfsClient = new IpfsClient("https://ipfs.infura.io:5001");
Introduce method to download the file by hash
public async Task<byte[]> DownloadAsync(string hash)
{
using (var stream = await _ipfsClient.FileSystem.ReadFileAsync(hash))
{
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
return ms.ToArray();
}
}
}
If you use web api - introduce controller to return exactly pdf
public async Task<IActionResult> Get(string hash)
{
var data = await _ipfsDownloadService.DownloadAsync(hash);
return File(data, "application/pdf");
}

Google Drive API - How to make sub-folder into the Team Drive

I'm developing small system using Google Drive API with JAVA,
I am wondering about the TeamDrive API among Google Drive APIs.
First of all, I created team drive folder,
Create Team Drive
public static void createTeamDrive(String accessToken) throws IOException {
long startTime = System.currentTimeMillis();
TeamDrive teamDriveMetadata = new TeamDrive();
teamDriveMetadata.setName("Team Drive API Test");
String requestId = UUID.randomUUID().toString();
TeamDrive teamDrive = getDriveService(accessToken).teamdrives().insert(requestId, teamDriveMetadata).execute();
System.out.println("[Create TeamDrive] execution time : " + (System.currentTimeMillis() - startTime));
}
and then I shared the user.
Share User
public static Permission ShareUser(String teamDriveFolderId, String googleMail, String accessToken) {
long startTime = System.currentTimeMillis();
Permission userPermission = new Permission().setRole("reader")
.setType("user").setEmailAddress(googleMail)
.setValue(googleMail).setWithLink(false);
try {
userPermission = getDriveService(accessToken).permissions().insert(teamDriveFolderId, userPermission)
.setSupportsTeamDrives(true).execute();
System.out.println(userPermission.toPrettyString());
} catch (IOException e) {
System.out.println(e);
}
System.out.println("[Give Permission] execution time : " + (System.currentTimeMillis() - startTime));
return userPermission;
}
And then I tried to create subfolder using google-drive library several times,
But I failed to create sub-folder continuously.
Create Sub-folder
public static void createSubFolder(String accessToken, String teamDriveFolderId) throws IOException {
long startTime = System.currentTimeMillis();
File fileMetaData = new File();
fileMetaData.setTitle("SubFolder Title ");
fileMetaData.setMimeType("application/vnd.google-apps.folder");
fileMetaData.setTeamDriveId(teamDriveFolderId);
fileMetaData.setParents(Arrays.asList(new ParentReference().setId(teamDriveFolderId)));
fileMetaData.set("supportsTeamDrives", true);
fileMetaData.set("fields", "id");
File file = null;
try {
file = getDriveService(accessToken).files().insert(fileMetaData).execute();
System.out.println(file.getId());
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("[Create Sub folder] execution time : " + (System.currentTimeMillis() - startTime));
}
When I call the 'createSubfolderFunction'
I can get 404 response like this.
com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
"code" : 404,
"errors" : [ {
"domain" : "global",
"location" : "file",
"locationType" : "other",
"message" : "File not found: 0AHGrQOmlzQZUUk9PVA",
"reason" : "notFound"
} ],
"message" : "File not found: 0AHGrQOmlzQZUUk9PVA"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
'0AHGrQOmlzQZUUk9PVA' is the exact result from createTeamDrive function.
I referred to this question.enter link description here
Please look at my source-code and point out what went wrong.
I found problem myself,
I should add setSupportTeamDrive(true) when I use the insert method.
file = getDriveService(accessToken).files().insert(fileMetaData).setSupportsTeamDrives(true).execute();
I thing issue with the your folder Id check its your parent folder id of google drive is correct or not
$folderId = '0AIuzzEYPQu9CUk9PVA';
Id is present in the google drive folder URL, after you open the parent folder

Cannot find files that I uploaded to google drive using google drive sdk

I am using .NET SDK for google drive.
I have successfully managed to upload a file on google drive but when I log in using browser cannot see the file there?
Here is my code:
private string privKey = "-----BEGIN PRIVATE KEY-----\MYKEYHERE-----END PRIVATE KEY-----\n";
private string[] scopes = { DriveService.Scope.Drive };
string serviceAccountEmail = "<myaccounthere>";
public File uploadToDrive(string uploadFilePath)
{
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = scopes
}.FromPrivateKey(privKey));
BaseClientService.Initializer initializer = new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
};
// Create Drive API service.
var service = new DriveService(initializer);
if (!string.IsNullOrEmpty(uploadFilePath))
{
File fileMetadata = new File();
fileMetadata.Name = System.IO.Path.GetFileName(uploadFilePath);
fileMetadata.MimeType = GetMimeType(uploadFilePath);
try
{
System.IO.FileStream uploadStream = new System.IO.FileStream(uploadFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
FilesResource.CreateMediaUpload request = service.Files.Create(fileMetadata, uploadStream, GetMimeType(uploadFilePath));
request.ProgressChanged += Upload_ProgressChanged;
request.ResponseReceived += UploadRequest_ResponseReceived;
var task = request.UploadAsync();
task.ContinueWith(t =>
{
});
return request.ResponseBody;
}
catch (System.IO.IOException iox)
{
return null;
}
catch (Exception e)
{
//Log
return null;
}
}
else
{
//Log file does not exist
return null;
}
}
private string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
mimeType = regKey.GetValue("Content Type").ToString();
return mimeType;
}
private void Upload_ProgressChanged(IUploadProgress progress)
{
Debug.WriteLine(progress.Status + " " + progress.BytesSent);
}
private void UploadRequest_ResponseReceived(Google.Apis.Drive.v3.Data.File file)
{
Debug.WriteLine(file.Name + " was uploaded successfully");
}
Does anyone happen to know what am I doing wrong?
Thanks in advance
If that doesn't work, you can try the suggested answer in this related SO question:
Since you are using a Service Account, all the folders and files will be created in this Service Account's Drive which cannot be accessed through a web UI and will be limited to the default quota.
To add content in a user's Drive, you will need to go through the regular OAuth 2.0 flow to retrieve credentials from this user. You can find more information about OAuth 2.0 on this pages:
Retrieve and use OAuth 2.0 credentials.
Quickstart: it has a quickstart sample in C# that you could use.
Using OAuth 2.0 to access Google APIs
Hope this helps!
Yes you are right. Service accounts have this limitation. For anyone that has the same problem what I did (using .NET) to overcome this was to enable Domain-Wide delegation and impersonate the account that I needed.
e.g my service account is srv1#myaccount.gserviceaccount.com impersonates srv1#gmail.com
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer("srv1#myaccount.gserviceaccount.com")
{
Scopes = new string[] { DriveService.Scope.Drive },
User = "srv1#gmail.com"
}.FromPrivateKey(PRIVATE_KEY));
When I login to google drive using srv1#gmail.com I can now see the files

Google Drive Android API onChildrenRetrievedCallback

I'm building an app and trying to view a PDF stored in a shared Google Drive folder in-app. I've already connected to the Drive and I have a GoogleApiClient already set up. Right now I'm querying the database and trying to handle the results, but I'm having trouble with this code:
Query query = new Query.Builder().addFilter(Filters.and(
Filters.eq(SearchableField.TITLE, "sample_pdf.pdf"),
Filters.eq(SearchableField.MIME_TYPE, "application/vnd.google-apps.file")))
.build();
Drive.DriveApi.query(googleApiClient, query)
.setResultCallback(new OnChildrenRetrievedCallback() {
#Override
public void onChildrenRetrieved(MetadataBufferResult result) {
// Iterate over the matching Metadata instances in mdResultSet
}
});
Android Studio is not able to resolve the class OnChildrenRetrievedCallback. I have imported the com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks package but I'm not sure what else to do here. Any help?
Try this:
/********************************************************************
* find file/folder in GOODrive
* #param prnId parent ID (optional), null searches full drive, "root" searches Drive root
* this is a String representation of DriveId (DriveId.encodeToString()
* #param titl file/folder name (optional)
* #param mime file/folder mime type (optional)
* #return void (arraylist of found objects in callback)
*/
static void find(String prnId, String titl, String mime) {
// add query conditions, build query
ArrayList<Filter> fltrs = new ArrayList<>();
if (prnId != null){
fltrs.add(Filters.in(SearchableField.PARENTS,
prnId.equalsIgnoreCase("root") ?
Drive.DriveApi.getRootFolder(mGAC).getDriveId() : DriveId.decodeFromString(prnId)));
}
if (titl != null) fltrs.add(Filters.eq(SearchableField.TITLE, titl));
if (mime != null) fltrs.add(Filters.eq(SearchableField.MIME_TYPE, mime));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
// fire the query
Drive.DriveApi.query(mGAC, qry).setResultCallback(new ResultCallback<MetadataBufferResult>() {
#Override
public void onResult(MetadataBufferResult rslt) {
if (rslt.getStatus().isSuccess()) {
MetadataBuffer mdb = null;
try {
mdb = rslt.getMetadataBuffer();
for (Metadata md : mdb) {
if (md == null || !md.isDataValid() || md.isTrashed()) continue;
// collect files
DriveId driveId = md.getDriveId();
String dId = driveId.encodeToString();
String mime = md.getMimeType();
//.....
}
} finally { if (mdb != null) mdb.close(); } // don't know if necessary
}
}
});
}
Your mimeType filter doesn't look right, either. I suggest skipping the mimeType filter, search by name(title) only and double-check the mime type you're getting (the md.getMimeType() in the code above).
BEWARE! File name/title IS NOT UNIQUE IDENTIFIER in the GooDrive universe
ONE MORE BEWARE! You will not see the file if t was not created by your Android App (see GDAA supported SCOPES).
Good Luck

Upload Files to Google Drive Using Service Account C#

I am building feature to upload files from my web application to my clients google drive. I don't want application to authenticate the user. Who ever is uploading any file from my file i want that to be uploaded to my client's google drive.
I am assuming that Service Account is the One which is used for this purpose. am I correct ?
When i upload the files using following code it gets uploaded to successfully but they are not visible under "My Drive". Then i added a permission which basically shares that file with my gmail account. and then it is visible under "Shared With Me" section.
I want those files to be available under "My Drive" section just like normal files.
Can any one point out what i am doing wrong here ?
private DriveService GetServiceInstance()
{
try
{
var certificate = new X509Certificate2(Server.MapPath("path to .p12 key"), "notasecret", X509KeyStorageFlags.Exportable);
string[] scopes = new string[] {
DriveService.Scope.Drive,
DriveService.Scope.DriveFile,
DriveService.Scope.DriveAppdata,
DriveService.Scope.DriveMetadata
};
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer("Client Email")
{
Scopes = scopes
}.FromCertificate(certificate));
// Create the service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Drive API Sample",
});
return service;
}
catch (Exception ex)
{
throw;
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
try
{
if (fu.HasFile)
{
DriveService service = GetServiceInstance();
Google.Apis.Drive.v2.Data.File body = new Google.Apis.Drive.v2.Data.File();
body.Title = fu.FileName;
body.MimeType = fu.PostedFile.ContentType;
FilesResource.InsertMediaUpload request = service.Files.Insert(body, fu.PostedFile.InputStream, fu.PostedFile.ContentType);
request.Upload();
// I want to eliminate this part. where i do not have to give permission. As i want these files to get stored on same google drive account for which i have generated this service account and client keys
Google.Apis.Drive.v2.Data.File file = request.ResponseBody;
Google.Apis.Drive.v2.Data.Permission newPermission = new Google.Apis.Drive.v2.Data.Permission();
newPermission.Value = "my email address";
newPermission.Type = "user";
newPermission.Role = "writer";
Google.Apis.Drive.v2.PermissionsResource.InsertRequest insertRequest = service.Permissions.Insert(newPermission, file.Id);
insertRequest.SendNotificationEmails = false;
insertRequest.Execute();
}
}
catch (Exception ex)
{
throw;
}
}
Don't use a Service Account. Embed a refresh token for the target account in your server. See How do I authorise an app (web or installed) without user intervention? (canonical ?)
I have created a specific folder and shared the folder to my email address. Uploaded the document to that folder. This resolved my issue.