I've got a working app that saves a document into a user-specified folder in their collection.
This works fine except when they want to save into their root folder.
According to the docs,
function testGetRoot() {
var root = DocsList.getRootFolder();
var folderName = DocsList.getFolderById(rootid);
Logger.log("Folder name: " + folderName.getName());
}
folderName shows 'Root' as the getName for the root of my collection.
So, seeing that I added 'Root' to the ListBox that is populated by the names of the other folders in my collection. That of course, was too easy..
**var collectionFolder = DocsList.getFolder(selectedCollection)**;
I get a 'cannot find folder Root' error message.
So I can get the Name of the root, but can't seem to get it to be accepted by getFolder method.
What am I missing?
You're not missing anything. You should report this issue in the issue tracker, as it makes sense. But as a alternative, which I'd probably use even if this worked, is referencing always to the folder id. e.g.
listbox.addItem(folder.getName(), folder.getId());
//then, later on in your handler...
//you'll receive the selected folder id directly, instead of its name.
//allowing you to use the more reliable getFolderById
var selectedFolder = DocsList.getFolderById(e.paramater.listbox);
//which works also for the root folder
I wound up hardcoding 'Root' in the logic where I addtoFolder, so that if the user selects Root, the addToFolder method isn't called. The default behavior is that the document will be saved to the Root collection, unless otherwise specified.
Related
Good afternoon. I am currently working on a project and I need to use python to get all the image_ids of the images in a folder. I have tried to use
query = f"parents = '{folder_id}'"
files = service.files().list(q=query).execute()
but for some reason this returns an id which is different to the real image id you can find in drive. Any tips?
Answer:
Your query parameter is malformed.
More Information:
The q parameter needs to be rewritten as:
'folderId' in parents and mimeType='image/jpeg'
where folderId is the ID of the folder in which you wish to search.
The q parameter allows you to specify properties of the files you are trying to list - so you're saying here "List all files that have a mimetype of image/jpeg, where folderId is contained in its list of parents."
Im suprised that works at all since parents use in not =
Example
To return all the files in the folder.
parents in '{folder_id}'
This would give you all the jpeg files on your drive
mimeType='image/jpeg'
You can put them both together using and
parents in 'root' and mimeType='image/jpeg'
I want to use PyGSheets to create a Spreadsheet in my Google Drive folder. I also want to be able to set the directory/folder where the sheet is created using the code. Specifically, I would like to type a string similar to a URL or even just the folder's name.
I have already looked at the PyGSheets documentation and the "Spreadsheet" model. I have not found any classes that accept a folder name or directory address. There is also no class used to move a sheet from one folder to another. Is either operation possible using PyGSheets?
As of May 5, I have used a work-around for this problem. To get the ID of a folder in my Drive, I right-click the target folder and select "Get shareable link" from the menu that appears. I copy the link and paste it on any text editor. The link looks like this: https://drive.google.com/open?id=9JHS74hgls049J50. I copy the random string of characters after the "id = " keywords. That is what I supply as a value when I create a folder using PyGSheets:
shtTargetedCreate = con.create("Test Folder",folder="1GwA4W8iv-26BvG48nKnEigYqDL8SpUGK")
Is there any more efficient way to do this?
Well it looks like you figured out how to create a new spreadsheet in a folder by file id, but haven't found how to get folder names / IDs from within pygsheets or how to move sheets. (You said you created a "folder using PyGSheets, but that just creates a spreadsheet, right?)
These can both be done by using the DriveAPIWrapper functions - https://pygsheets.readthedocs.io/en/stable/drive_api.html
Folder names / IDs:
pygsheets.drive.list(), in your case con.drive.list(), will give a list of metadata dictionaries for all files and folders in the drive. I've made a simple function to extract just the folder names (keys) and ids (values) into a dictionary for simpler lookup and use with the create method:
def folder_id_dict(client):
folders = {}
meta_list = client.drive.list()
for file_meta in meta_list:
if file_meta['mimeType'] == 'application/vnd.google-apps.folder':
folders[file_meta['name']] = file_meta['id']
return folders
#your use:
names = folder_id_dict(con)
Moving files between folders:
https://pygsheets.readthedocs.io/en/stable/drive_api.html#pygsheets.drive.DriveAPIWrapper.move_file
con.drive.move_file(file_id, old_folder, new_folder, **kwargs)
I am stuck on this and the other posts I have read on here are not useful. So I've reached a point where i need to ask for help after many hours on not resolving what I feel should be a simple task. I program in Swift usually and really know little about html or javasript.
I am building a simple webpage to log-in to Firebase and a second linked page to upload data to a database. Both work fine. The problem is getting the uploaded data to link to the uid of the current user.
So I am logged into an existing user with it's own uid. How do I then upload the data to the current user did in the database? Should be simple but I am just not getting it :-(
Code for uploading data is as follows (note I have tried using both set and push):
// Generate a reference to a new location and add some data using push()
var postsRef = ref.child("users");
var newPostRef = postsRef.push({
// var newPostRef = postsRef.set({
name: _name,
property: _property,
email: _email,
phone: _phone,
Any help, or better still a working simple example would be useful. I have read the docs on Firebase, so please don't direct me there :-)
Many thanks in anticipation
It is a best practice to create a new database node using the UID generated by the account creation as the path after /users.
Right now, when you push data into /users, Firebase creates a uid for that particular array item that does not correspond to the UID of the user.
If you use set, you need to specify the path you will set which should include the long UI: /users/longGUIDhere
You can get the user id with something like this (from Firebase docs):
var user = firebase.auth().currentUser;
var name, email, photoUrl, uid;
if (user != null) {
name = user.displayName;
email = user.email;
photoUrl = user.photoURL;
uid = user.uid; // The user's ID, unique to the Firebase project. Do NOT use
// this value to authenticate with your backend server, if
// you have one. Use User.getToken() instead.
}
And then you shouuld use uid to populate the path like below to save their info:
function writeUserData(userId, name, email, imageUrl) {
firebase.database().ref('users/' + userId).set({
username: name,
email: email,
profile_picture : imageUrl
});
}
I know you asked not to be referred to the Firebase docs, but it also looks like you are using an older version of the SDK, so that could be part the issue as well. I recommend taking a look at these two page, since that is where I pulled these verbatim examples:
https://firebase.google.com/docs/database/web/read-and-write
https://firebase.google.com/docs/auth/web/manage-users
var postsRef = ref.child("users/current user id or json key");
this will help you to update the details of current user.
I'm using the firebase/polymerfire package from bower bower install firebase/polymerfire
how can i create some data in the database after a method has been triggered?
The document tag looks like it will display and update data. I would like to, when a user signs up, create some data for the user to use.
app.signInAnonymously = function() {
this.error = null;
this.$.auth.signInAnonymously();
// add default data for the user template
};
How can i use the default set() or push methods like the normal SDK?
How can i call this on an event from JavaScript?
When trying to bind a path to my document like
<firebase-document
path="/"
data="{{firebaseData}}">
</firebase-document>
{{firebaseData}}
the data won't display, but I have authentication working.
You can actually use the firebase api directly there since firebase-auth is already including it, but if you want to keep the element-based functionality you could do this:
Add an empty firebase-document to your template
<firebase-document id="mydoc"></firebase-document>
Then call its save function in your element
app.signInAnonymously = function() {
this.error = null;
this.$.auth.signInAnonymously();
// add default data for the user template
//set path to null somewhere to avoid overwriting data, I recommend doing it here since save's path update is lazy
this.$.mydoc.path = null;
//set data to the value to set/push
this.$.mydoc.data = {/*your data*/};
//call save, if the second parameter is falsey it'll call push to the first parameter if it's truthy it'll set the data to firstparam/secondparam
this.$.mydoc.save('path/to/users', userid);
};
As for getting data with firebase-document, check that you actually have data in your database and your security rules, if you still can't see your data then it might be related to this issue, do bear in mind that polymerfire is still in a pre-release state
I am creating userproperties with PropertiesService, as
var userProperties = PropertiesService.getUserProperties();
for storing users single token for my add-on , When i set usertoken in userproperties with a key pair value as, userProperties.setProperty('USERTOKEN','token'); in an document.
Once i do this as per the userproperties scope i can retrieve the user properties value from any of the document by using userProperties.getProperty('USERTOKEN'); but,
When i do that the value is null (i.e), i cant retrieve the 'userProperties' value from other documents,
So that, the scope of the userproperties fails. The userproperties value is associated only with the particular document where it's created.
once my add-on is installed i used to check every time userproperties value for all documents ,
if(value)
{
retrieve data;
}
else
{
authorize;
}
Thus value is null and the user is made to authorize everytime for every new document. Since my add-on cant retrieve the value from userProperties.getProperty('USERTOKEN');
According to the documentation at Properties Service - Saving Data:
"Script properties can also be saved via the script editor user interface by going to File > Project properties and selecting the Project properties tab. User properties and document properties cannot be set or viewed in the user interface."
I'm not sure what it means but I think it means that even if you are able to set the property using script, the value will not update if you view it in File > Project Properties > User Properties.
But it doesn't mean that the property was not updated though. However, if it's a Script Property you set via script, the value will update in your view.
This I say because I tried it by setting it inside the doGet(). See the example below:
//Set properties as global variables
var userProperty = PropertiesService.getUserProperties();
var scriptProperty = PropertiesService.getScriptProperties();
function doGet() {
userProperty.setProperty('uservar', 'Hello');
scriptProperty.setProperty('scriptvar', 'World');
Logger.log(userProperty.getProperty('uservar'));
Logger.log(scriptProperty.getProperty('scriptvar'));
return HtmlService.createTemplateFromFile('index').evaluate();
}
I did it inside doGet() so that I can check it simply by refreshing my WebApp page.
Interestingly, the log shows the correct values (Hello, and World).
But if I visit the File > Project Properties, only the Script Propery value was updated, the User Property remains the same as the original value I set it for.
Hope this helps.
For some reason it seems that the PropertiesService does not work. Even when I use Google example in https://developers.google.com/apps-script/guides/properties#reading_data I am getting nulls. I have reverted back to the old UserProperties and it works, however it is supposed to be depreciated...
PropertiesService seem to be working for script properties though.