This is my first ever question on StackOverflow so I hope I am able to do it properly.
I am trying to achieve a solution to a problem that I have been trying for a few weeks now. My needs are as follows:
- Administrator able to save files in Google Drive in a specific folder for the app.
- This folder will have subfolders and each subfolder can have files (Docs, Slides, Drawings, Spreadsheets).
- An excel spreadsheet that will list all these files with their ID, can be generated using Apps Script easily.
- The spreadsheet can then be imported into Flutter App. Example here.
- Now when a user selects the file list item in the Flutter App, I want to show the selected file content inside the flutter app without having to download it as separate file. (This is where I am having issues).
I have tried and managed to get the blob of the file, but that's where I get stuck. I don't know how to use that blob in Flutter.
Here is my trial Google Apps Script code: (its not complete but just an example to get blob)
function doGet(e){
//var params = JSON.stringify(e);
var appFolderId = "1HsJZytwvtNZJK9x7Q6AZNosN6_addjLo";
//var appFolderName = "";
var appFolder = DriveApp.getFolderById(appFolderId);
Logger.log(appFolder.getName());
var filesJsonString = JSON.stringify(getFilesInFolder(appFolder));
Logger.log(filesJsonString);
//return ContentService.createTextOutput('Hello, world!');
}
//Return json object containing array of file objects.
function getFilesInFolder(folder) {
var filesArray = [];
var files = folder.getFiles();
while(files.hasNext()){
var fileObj = {};
var file = files.next();
fileObj['id'] = file.getId();
fileObj['mime'] = file.getMimeType();
fileObj['name'] = file.getName();
fileObj['desc'] = file.getDescription();
fileObj['url'] = file.getUrl();
fileObj['download'] = file.getDownloadUrl();
var fileBlob = file.getBlob();
var raw = fileBlob.getDataAsString();
fileObj['blob'] = raw;
filesArray.push(fileObj);
}
return {filesArray};
}
The result of this code is as follows, (if you scroll to the right it will show a huge blob):
[20-10-17 04:30:35:653 PDT] MyApp
[20-10-17 04:30:37:325 PDT] Logging output too large. Truncating output. {"filesArray":[{"id":"1wzR-7fWT_vA28j82scazk7jVSUnDwSjkwjvup8Ovr9k","mime":"application/vnd.google-apps.document","name":"MApp Readme","desc":null,"url":"https://docs.google.com/document/d/1wzR-7fWT_vA28j82scazSjkwjvuk7jVSUnDwp8Ovr9k/edit?usp=drivesdk","download":null,"blob":"%PDF-1.5\n%����\n2 0 obj\n<< /Linearized 1 /L 18715 /H [ 750 126 ] /O 6 /E 18440 /N 1 /T 18439 >>\nendobj\n \n3 0 obj\n<< /Type /XRef /Length 51 /Filter /FlateDecode /DecodeParms << /Columns 4 /Predictor 12 >> /W [ 1 2 1 ] /Index [ 2 24 ] /Info 11 0 R /Root 4 0 R /Size 26 /Prev 18440 /ID [<df70ed3aa3e7587759206db70489ab30><df70ed3aa3e7587759206db70489ab30>] >>\nstream\nx�cbd�g`b`8\t$���XF@��\u000eDh\u0001\t\u0016[ a�\u0000�-g`bܫ\u0000R��H1\u0001\u0000�l\u0005K\nendstream\nendobj\n \n4 0 obj\n<< /Pages 23 0 R /Type /Catalog >>\nendobj\n5 0 obj\n<< /Filter /FlateDecode /S 36 /Length 49 >>\nstream\nx�c```e``z�\u0000\u0004.s\u0018�\u0000�f\u0006b\u0016�(H-\u001830j1�10\u0018��6�r_`\u0000\u0000�i\u00054\nendstream\nendobj\n6 0 obj\n<< /Annots [ 14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R ] /Contents 7 0 R /MediaBox [ 0 0 596 843 ] /Parent 23 0 R /Resources << /ExtGState << /G3 12 0 R >> /Font << /F4 13 0 R >> /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /StructParents 0 /Type /Page >>\nendobj\n7 0 obj\n<< /Filter /FlateDecode /Length 1013 >>\nstream\nx��mk�0\u0010���S����t��\u0003�A۴}�\u0011�\u0007�� �u�\u001f&;m,��\u0013۩�Y�@IO9��$�O\u000f�U&��l�\u0013٩o\u000f�秊H�Y@:I��\u001e4_?�_�L\u00071�R�No�_V��}�U�\u000f�����S��:Cbe-����ŒlX'2\u0014�/���݇���9��_a�%�WTۻ���\u001a�}hr=g�$���>\u001a��'���$\u001d�xíC�\u0002�\u0015\u0004�(Z��\\�����x��+\\u\u0005N�x���\u001a�+�ڊ�&�\u001a\u0012��2�� a_`-(�\u000bT\u0015�-�U�\r��#���\u0018BkMW`I��!���8\u0014+\u0003�\u0003j��.Ov��l�xM��m�B�-\u0014xS��ُv�I��0\u001cs}�\u001fWh\u0012�h\u0004�t\u0004�\b�r胻F\u0005pȖ�\u000e���^�[\u0005Gl���@݀�\u0016\u0010\u0010l�\u0015�\t\f4�@\u000eF\u00011rΡ��9�����N\u0003\u0001'��� %\u000f�\u0006@�C\u001b��.���-g���\u0002\u000e��>�D\u0003\\\u0000�\f\b�ݠ$Js\u000b\u0006\u0013h�\u000fD\tI�FA\u0005\b\"�\u000f\u0014\u0010l\u0014JA0�o\u001e̓�20���S�<�se��ƺ�!2�\u001c(YO���\u0002�\u0019%��?�k&���)�~��(��0]��\u0010��I�i��0���)˹)$�K�\u0003\u0015�d�p/���'\u0002��\u0004�X\tP\tP\tP\tp�\u0004�QE\r�ɅRA�;���c\u001b\u001a���K`\u000f\u0007!)`\u0004\u000fBa\\1T7 \u0016�7�\u000b�v�y�7x�Ir���Z��\u0015�\u0015�\u0015�\u0015��\fܝ��h�L1�\u001f�\u000e��c�D,Z���V~���皟k~���\u001d��7O��И�\u0002����\n�(\u001a\u001bh,��]�\u0011\u001b\rgudם��9Ӄl2���u)H��@�`�`�`��)R��\u001d\u000b��B\u0007А\u0007\u0000��\u0018|�\u0005�*��8��\f|�\u0004�\u001b�2�\u0005��s:�\u001eC~�K��k\u000b�嘛2\u0013\u0007�����Zd�\u001a�2i&�]�����N��X�uZ]��uZ]��/���!\u0007&=\u000f],�\u000ed�#Ϊ��]��k���5���_�M�/6��ŐP���a\u0013�ŌSf�O:\u0007�}֤��\u000b���q���s\u0003�-�-�-�-�]������\u0011��}2\u0014\u001d���0Q\u0003G_��ѻ;�\u001e1K\u0000�t��?F9���l�\u0011��Ry\n���uF���\n���z+��s)�I91�$F��\u0017\u0012��$I)�\u0013�\u0007_�^��[H�d�+$�X1�\u001b���\u0001��b\u0005endstream\nendobj\n8 0 obj\n<< /Filter /FlateDecode /Length1 24164 /Length 14664 >>\nstream\nx��|\tt\u0014U��}�������}M�;��,\u001d\bd!\u000b�t a1�]H ��o\"\tau\r�,�\u000b2���;�ф�\u0001ud\u0014u\\\u0010\u001c��\u0019\u0005\u0015�Q\u0006�AFŤ���C\b�����|�;������{��w߽��\u0001\u0002\u0000\n\u0002\u000f0j\\n��1;}\u0000D��\u0013&T�Ԏ�8�;��\u00000�>}��&^��\b`�\u001e�\u001f��tq`S�\u001f�\u0002X�\u0003����4{���m���&�\u0010�=��\t\\�\u0005�_͞2��\u0015�\n�>�\t@�\u0006��4gƂ���V�\u000b`�M\u0000Zi�̩3^/9s+�_��\u0007��\u0002�\u0002�1\u001c��O��`��u\u0016�d�w���_�p�ԯ2>����?�v���M\u0002��5��~�\u000f\\1u���Ճ�����t�ʼnl�\u00040���7-����S�8�q8?�\u0013\b��l\u0000\u0001�~���=�ɘ{\u001bfQ�$P����B^\u0001\u0007����W,�\u0018\u0004�)ᝮ1$_\u001cD�b@\u0012�Dw\u0003\u000e8�.��\b%\u0004\\�7�}�\u0000\t�D\u0017�H��\u0004\u0019dD\u001d�\u0010��G4�\u0001Ѩ�\t��\n�\u0010͈?�\u0005̈V� ���hG<\u000b\u000e�!:���B�\u0011��Ĵ\u0007ܘ��\u0007ѧb\nx\u0011S���\u0001�*\u0006 \u00051\b~�4\b �\u0010��t\b\"�!\r1��\u000fȀ\u0010b&�#fA\u00041[�(d$�@\u000ed\"�Q�/d#�B\u0014�\u001f�A��\u001d�A_�|�E,�~��P��\u0000�X\u0004���P��;��X\n��\u0003U,�\u0001�\u0017A\u0011� (F,��ķ�\n��\u00150\u0010q0�!\u000eA�\u001bT�E�U0\bq(�'N�0�!\u000e�\n�\u00110\u0018�b\u0015�a\b�%P�X\u0003C\u0013'a���`\u0018�h\u0018�8\u0006F$�\ncU\u001c\u0007\u0017#����\t�\u0014j\u0010'�8\u0011F\"�¨�7P\u0007�\u0011'!���0\u0006��0\u000e�\u0001�#^��\u0014�4�54�\u0004ĩ0\u0011q\u001a�_`:�!I�3a2�,�O|\u0005�U�\u0003\r�s�ė0\u000f\u001a1=_��a*�\u0002���W�tą*6���\u0017�\f3\u0011\u0017�l�\u0016\u0015\u0017Ü��\u0004�\".�y��\u0010?��0\u001fq\u0005,@�\u0012�@�Jūa!�5Єx-4'��u*�B\u000b�JX��+X��\u0014����7��\n�%>�հ\u001cq\r�@\\\u000bW\"�\bW%>�up5�z�\u0006KnB�\u0018n�k\u0011o��\u0010o���\u001b\u0010��m�+čp=���Q�]�;`\u0015�&X�x'��ڻ\u0010���p#�=�.�\u0011�\u000b�\u0011\u0010�W�7p\u000b�f�\u0015q\u000bl@|\u0000�Cx\u0010nC|\b6\">\f�F|\u0004nO�\u0019\u001e�;\u0012��`\u0013�V�\u0013q����]�O�݈O½�O��4܇�\u001d�G��o\u0010w \u001e�6،�\u0013� �Ã�ð\u000b\u001eJ�\u0011v��\f<��\u0001� �G\u0011���,lE|\u000e�%>���q�ߪ�\u0002<��\u000f�D�\u001d<��\"<��\u0012lO�\u000f�!��2�H�\u0007���*�!�\u001ev&ޅנ\u001d�u�\u0006�F|\u0013�A<\u0000\u001d�o�\u001eă*\u001e���o�s���\u0013��;��w᷈��\u000b��þ������\u0017\u0011\u000f�K�G`?�T�3���!���\u0011��8\u0004GU<\u0006�%\u000e���:�'�\u0006�*\u001e�7\u0011?�\u0003���[�_���[�_�ۈ�?$\u000e���\u000e�7*��w\u0011�\n�'ބ��\u0001�)\u0015�\u0006D�\u0016\u000e#�\u001d� �V�;�s�\r8\u0003\u001f\"�\u0003>B�\u001e�u�\u0001�\"�\b�\u0010��Lj?��\t�&^�.8����\u0010��������������m��տ��_�L��/t�\u0017?���\u001b:�x�N_t�N��_��OU����t�'�N���N�D�韨:��^:����c�N?���c��:���#���u�u��N�O���su����������Y����\u0003�\u000e@����\u0010�\u001a�(���5�ކ!�P\u0017����A�1\u0019u�\u0014ܹ�pwm�UKt���O-���n���_��\u0013��g�o/a/�1x����G��\u0000���Z\u0001㮹�/Y=��_�qGw\u0000����\\��\u0017�Er\n{mG�lG�q�n�\u000f���5��~��y,�\u0002��N܉v��\u0003ȋ\u0007P���\u0015�E9v\u0010\u0017��`\u0015�\u000e�Z��\\\u001a�v4ꨛ�%�%�\u001d����\tp\t�&Қ�Mܒؘx\u0018��\u001e���\u0019�A�8\u001d���\u001fqG��\u001ew�.?J6jw�\u00190\u0011��\u001e�~�p�p\r<I��S��Sm\u0019��G�\u001e �h\u0014�τ/��\\�\rA*\u000f%���ʇ����b/)$�hP�OԠ\f9�\u0019ˑ�ݸkw�݁{�\b�\u000b�\u0012\u000f�9���n\u0004Χ\u001d�\"���Ε]��ȥ,<�F�~���\u0010\t��х�^�\u0013b��lx\u0012^��}\f{~N�A���:�\u0015~hb0���P�!�q�~L<$��\"\u0013h\u0016]H�-B�!\u0007���sa.��.��\u0011���TO\u000fr\u000f�O�g5)]�\u0012F\\�\bj���wĀ3\r�\u0016�+�>��\u000e�S��\u0013�v~\u001b�\u0007q*��2<-nF��\u000fb!�d\f�L搫�\u001ar\u001b��\u001c �ȗ������In\u000e��=�\u000f�{\u001c��_/�\u0016�k������v�?\u0012y��x>^�g�m�&����A�q\u0018��\t\u0011��\u0018�\u000e� ��\\����f� �J��v|�!�\t��|K�#g)n%��^\u001a�ix��\"���N�\u0007�>D��?pN.��r�\\\u0019W�-�Q��6ཋ����\u0007�\u0004�9O�$l\u0016�\nO\b/\n�4z�Whp���C�ٝ\u001fuA�ڮM]m]�x��q\r=�\u0005?Z\u0016cp�M�=�\u001cO�GP��!z䝇d�A�\u0012��\u00142�4����\u001b�=�\u0011u�O��K\u001f��8f\u0003��c�K\u000b�`:\n���L�L7Ѝ���O�DNǙ8;��\r�\u001a���bn\u0005���sor\u001fr�pg���N�2����\b\u001f��S�%�o�/�/�z�\r�3��Y�Y����M\u001c \u000e\u0012G�c�\u0006�Vq���Ԉ��\u0012�$�����\u0018����v�-4�wӷ�[(�S`\u0006WCQR�V��^C�i��\\3�\u000e$#�\u0014\u001fA^�B7�3t WC��8�G�'�il��\u0018��/�\t�9��[Hy�FO��'5zh#@K�/s��(�\u0006\u001c�\u0012�\u0000����IN�Ǹ�(\u0005��Z\br���\\3�\u0006v�*\u0000��t\u0013��H�8��$�|�%��#Q��8fĶD��\f�;�\f~6�\u0006��j<\u000b\u001e�]�%\\�����kt.��ZI;P~\u001bή��\u0013N��\r���Gs�\u001eF;� /�Gܓ8���i��?%�%sp\u0007\\��Isb%�\u0010j�?����\t\u0010�}q5��\u00071F;\u0007�M.rم��\u0003*�\u001a,q��\\�rq)j�{�\u000b�\u0004�\u00124\u0017��D�boA�f<�ق���\u0001���\u001a�6ݣh-�F�j#Z���r5R܊�ܭ����\n�T�9\u001f�K����04ч����8����En��\u000bO����1\u0014\u0006\t��:�\u0003<=�\u00137�YoG;=\rG6\rm��8˿�\u0013�s� �k$ݑ\u0018�5�|��]�X�Od�\u0004/Gk�9xD\u0014`�\u0018�UT��\u0007]T6������ ?��ܾ}r��Y�\u0019�pz(-\u0018���\u001e���۬\u0016�b2\u001a�:Y+�\u001a��(������@<�\u0018�#�����|h*\u0016L�U�\u0018\u000f`��\u000b��\u0003�j���-c�r�?��%[�zZ\u0012%P\u0006e}r\u0002U�@�@e(�A&����͕��@����Q�\u001bԴ\u
Interestingly, the contents of this file are just a few lines of text and links in a Google Doc, but the blob is huge.
Script.google.com - Script project created
https://developers.google.com/apps-script/guides/content
https://developers.google.com/apps-script/guides/services/authorization
https://developers.google.com/apps-script/guides/web
https://developers.google.com/apps-script/guides/web#permissions
https://developers.google.com/apps-script/guides/services/advanced#enabling_advanced_services
https://developers.google.com/apps-script/advanced/drive
https://developers.google.com/apps-script/reference/drive
https://developers.google.com/apps-script/guides/services/quotas
At this stage, I am wondering if I am on the right track. I know Flutter can use Firebase as a database to store app data, that might be easy to search, filter and scale up. But, from an Admin point of view, it's easier for someone to add files to Google drive. Flutter cannot directly show Admin's Google Drive files using Google Drive API (it gives access to logged in user's drive files instead). Hence, I am taking Google Apps Script approach.
Edit: I found another page that does similar thing but relies on web browser to show file or allow download. Is it possible to display blob in Flutter app itself? Or a dependency that will automatically show Google Drive file in Flutter app as is.
Flutter web - display pdf file generated in application. (Uint8List format)