I'd like to have an assets folder (and maybe it also has in terms some subfolders) under functions folder which contains several image files. Depending on database action I'd like to copy some or all contents of that assets folder (or one of its subfolder) to Firebase Storage location designated with that particular db action. (or under temp folder for editing prior to sending them to Cloud Storage location)
Is this possible? I can't find any relevant information.
I know I can put those assets under Firebase Storage in the first place, I just want to keep them under functions in terms of keeping my project structure clean. Also, any operation in Cloud Function area of Storage is per file, no bulk folder ops.
UPDATE:
Indeed it is possible, one needs to use correct file/folder location in Cloud Functions while using a custom sub-folder. I'll write an answer later when I'll have free time.
You can indeed deploy an assets folder along with your function code. For example, consider the following directory structure:
functions
│ index.js
│ package.json
│
└───assets
│ file_1.png
│ file_2.png
│
└───subfolder1
│ file_3.png
│ file_4.png
│ ...
Running the firebase deploy ... command within the functions folder will deploy the whole tree. Then, from your exported function in index.json, you'll be able to access your assets folder content like you'd usually do in Nodejs.
One thing to take into account with this approach though is that there are resource limits applied to Cloud Functions, specifically on deployment size:
Depending on the size of your picture this may be a problem. And note that, even if the total size is within the limits, the bigger it is the longer it will take to deploy when scaling up.
I tried the above solution but falied
you can convert your files in base64 and top of your function you can convert the bas64 file to your files and save it in os.tmpdir() and use it anywhere in your function.
Here is the example of how I put my font in cloud functions for later use
function writeFontsInTempDir() {
const banglaFont = 'Your base64'
fs.writeFileSync(path.join(os.tmpdir(), 'bangla_font.ttf'), banglaFont, {encoding: 'base64'});
const englishFont= 'Your base64'
fs.writeFileSync(path.join(os.tmpdir(), 'english_font.ttf'), englishFont, {encoding: 'base64'});
}
for later use, you can just call
const bangla_font_path = path.join(os.tmpdir(), 'bangla_font.ttf');
const english_font_path = path.join(os.tmpdir(), 'english_font.ttf');
You will need these imports
import * as os from 'os';
import * as path from 'path';
Related
Let's say I have an invoice to generate and the invoice contains the company's logo and other images that would be used each time an invoice is generated.
Would I have to pull those images off the storage bucket? Or can I load it into the functions directory and use it from there, similar to how the serviceaccount.json file is loaded into functions?
EDIT: The way I'm thinking of is
functions/
├── index.js
├── image.jpg
And in index.js
const path = require("path");
const pathToImage = path.join(__dirname,'/image.jpg');
The Firebase/Cloud Functions deployment process packs up everything in your functions directory, and deploys it to the runtime for your functions. This means that you can indeed include any static files you need in the Cloud Functions deployment, and then access them from your code.
This is how you also include your service account, or what happens when you split your Cloud Functions code over multiple files that you then include into index.js.
In my Meteor 1.10.2 project, I have created a folder called assets inside the /public/ folder. When the Meteor application is built, I find this assets folder has been copied to these locations, as a direct child of the web.browser... folders:
/.meteor/local/build/programs/web.browser/assets/
/.meteor/local/build/programs/web.browser.legacy/assets
However, if I rename the folder to Assets (or if I give it any other name), when the application is built, I find it deeper in, inside the app folder at:
/.meteor/local/build/programs/web.browser/app/Assets/
/.meteor/local/build/programs/web.browser.legacy/app/Assets/
What is the logic behind this? What is the intention? What are the best practices for working with a folder at /public/assets/? Are there any other words that are given special treatment when used as names for folders inside the /public/ folder?
FWIW, this behaviour is specifically due to meteor tools bundler:
https://github.com/meteor/meteor/blob/release/METEOR%401.10.2/tools/isobuild/bundler.js#L719-L725
setTargetPathFromRelPath(relPath) {
// XXX hack
if (relPath.match(/^(packages|assets|dynamic)\//)) {
this.targetPath = relPath;
} else {
this.targetPath = files.pathJoin('app', relPath);
}
Therefore we can see that there are 3 special directory names that exhibit this special behaviour:
packages
assets
dynamic
Example with public assets:
These assets bundled in build:
For "packages", while we can understand that this is how Meteor ships the static assets of packages (i.e. when they call api.addAssets(), we can also see that there is a potential for collision, in the (however unlikely) case we use a pathname like "public/packages/my-package-name".
As for "assets", the initial name was "static", but I do not think it was publicly documented either.
And for "dynamic", I do not know yet what is its exact purpose, but we can see that it serves its content as "javascript" type (at least SVG files), whereas the first 2 serve them as "text/plain".
What Meteor does is build your project multiple times. Once for legacy web browsers, and again for a modern browser, and also for other platforms such as IOS or Android. It does all this inside the .meteor/local folder as you have observed.
Meteor has the concept of a /private folder, which is similar to /public, except that Meteor thinks of them as assets. This might explain why your folder appears in different locations, depending on the name.
Personally I wouldn't worry too much about how Meteor handles files, unless you want to become a contributor, in which case you are welcome to poke around :)
I hit following problem working with firebase functions, I split functionality into different files, few of them have only custom utility logic.
The thing is that with firebase CLI I only can upload separate functions with :
firebase deploy --only functions:someFunction
But in this case the utility file which function someFunction uses does not get uploaded. To refresh logic in separate files I need to redeploy all the functions by executing :
firebase deploy functions
and I hit deployment limit just in few deploys.
Is there any way I can redeploy a separate file to the server?
UPD
By utility file I mean files that contain logic and used in functions. Say we have function someFunction in the index.js that goes like this :
const commons = require('./commons');
exports.someFunction = function() {
common.sayHello();
}
In this case commons is a plain javascript file (commons.js) that has utility functions, other words - utility file.
exports.sayHello = function() {
console.log('hello!');
}
This is exactly the file I would like to redeploy separately.
It's not possible to upload only a single file when when deploying functions. The entire contents of the functions folder (except node_modules) is replaced for every function at every deployment, even if you are deploying just one function at a time.
I have some code that is used on both the client and the server, that I need to be loaded before all code in server/ and client/
I tried to put the common code in lib/, but then I run into issues when I have code in client/lib and server/lib that depends on the code in lib/ to be defined when they load.
Here's an example of file load order from the Meteor documentation under the section File Load Order:
nav.html
main.html
client/lib/methods.js
client/lib/styles.js
lib/feature/styles.js
lib/collections.js
client/feature-y.js
feature-x.js
client/main.js
According to this example, files in client/lib/ get loaded before files in lib/.
I need the files in lib/ to load before the files in client/lib/. Is there any way to change this?
I'm putting my collection definitions in lib/, and my client subscriptions in client/lib. Organizing it like this makes sense to me because, my helpers in client/helpers.js depend on client/lib/subscriptions.js, and my subscriptions depend on the collections defined in lib/collections.js, and both the client and the server need the collection definitions, so I put them in lib/.
I found a clever solution.
I essentially renamed ./client/lib/ to ./client/deps/, which changed the load order to the following.
./lib/collections.js
./client/deps/subscriptions.js
./client/helpers.js
I need this order because my subscriptions depend on a collection being defined, and my helpers depend on subscriptions being defined.
The folder ./client/lib/ will always be loaded before ./lib/, but ./client/deps/ will be loaded after ./lib/ and before ./client/helpers.js, because ./client/deps/ is a deeper folder than ./client/, as per the Meteor documentation on File Load Order.
In CodeNameOne, I am using the following code to create a new folder but it's not working. I am testing in android simulator and mobile.
FileSystemStorage storage = FileSystemStorage.getInstance();
storage.mkdir("tizbn");
Codename One's FileSystemStorage requires absolute paths to all files, you need to either construct a path from the roots or from the app home method. Your statement assumes a current working directory which is problematic on a phone.