Firebase Functions— Scheduled Job That Changes Your Remote Config
I abandoned my old laptop that has been running my cronjobs for years
I’ve been developing indie apps for Android and iOS for more than 6 years. In spite of I am a full-time developer, not a digital nomad, I’ve moved 6 times and lived in 7 different flats -in 3 different cities and 2 different countries- during that time period. It was really hard to carry my old grumpy laptop with me, make sure it is always plugged in and has access to a stable internet connection.
I developed numerous apps last 6 years:
- Without backends that run fully offline
- By using 3rd party API interfaces but not backend maintained by me
- Sometimes I was the one who developed the backend and maintained it
- And most of the time I used Firebase as a backend
As an indie developer who creates the business model, develops the application, answers all the emails and requests from customers, does the marketing; it can be hard to keep track of the things going on.
But one thing is certain: you want your app to keep running without crashes and other software-related problems. Firebase does its job pretty well in that manner.
Firebase is working as a kind of half-baked backend solution. Once you use its capabilities such as Real-Time Database, Cloud Functions, Remote Config or Cloud Storage you can fulfill most of the requirements of your backend needs without a need for maintaining a host machine in security, scalability, and fault tolerance manners.
Pricing Campaign via Remote Config
I run pricing campaigns to take my users' attention. I basically set 2 different prices for each in-app purchase item. I decide whether I will show the expensive one or the cheaper one according to a configuration. I use Firebase Remote Config to run this campaign without a need for an app update.
I keep my config on Firebase Remote Config like below:
{
“discount_start_date”:”2021.10.23 00:00:00",
“discount_end_date”:”2021.10.26 00:00:00",
“discount_type”:”_discount_common”,
“discount_rate”:”0.74"
}
I retrieve starting date, ending date, and discount rate to show the discount percentage and countdown timer to my users.
And, I use discount_type to decide the type and select in-app purchase items accordingly.
Your First Firebase Function
After creating the project on Firebase, setting up the project on your local and initializing the project by using command-line tools, you will get a directory structure like below:
your_project
+- firebase.json # Describes properties for your project
|
+- functions/ # Directory containing all your functions code
+- package.json # File describing your Cloud Functions code
|
+- index.js # Main source file for your Cloud Functions code
|
+- node_modules/
Here index.js is the starting point. You will start writing your functions there.
const admin = require('firebase-admin');
admin.initializeApp();
Deploying a Scheduled Function
Documentation says:
If you want to schedule functions to run at specified times, use functions.pubsub.schedule().onRun() This convenience method creates a Pub/Sub topic and uses Cloud Scheduler to trigger events on that topic, ensuring that your function runs on the desired schedule.
In my case, I call my function to set my discount_end_date as 2 days after the function's running date. And, I want to run the function every 47 hours.
exports.scheduledFunction = functions.pubsub.schedule(“every 47 hours”).onRun(() => { setupCampaignConfig(); return null;});
My scheduled function calls setupCampaignConfig() on every 47 hours now.
1- Create a new config: getUpdatedConfigTemplate()
2- Validate the template (optional but I highly recommend validating): validateTemplate()
3- Publish the new config: publishTemplate()
(You can visit the gist to have a better code viewing experience)
function setupCampaignConfig() {
getUpdatedConfigTemplate().then((template) => {
validateTemplate(template);
});
}async function getUpdatedConfigTemplate() {
var config = admin.remoteConfig();
const template = await config.getTemplate();
var templateStr = JSON.stringify(template);
let values = template["parameters"]["discount_info"]["defaultValue"];values.value = "{"
+ "\"" + "discount_start_date" + "\":\"" + timeUtils.getDifferentDate(-1).toString() + "\","
+ "\"" + "discount_end_date" + "\":\"" + timeUtils.getDifferentDate(2).toString() + "\","
+ "\"" + "discount_type" + "\":\"" + "_discount_common" + "\","
+ "\"" + "discount_rate" + "\":\"" + "0.74" + "\""
+ "}" return template;
}function validateTemplate(template: any) {
admin.remoteConfig().validateTemplate(template)
.then(function (validatedTemplate: any) {
console.log("Template was valid and safe to use");
publishTemplate(validatedTemplate);
})
.catch(function (err: any) {
console.error("Template is invalid and cannot be published");
console.error(err);
});
}function publishTemplate(template: any) {
var config = admin.remoteConfig();
config.publishTemplate(template)
.then(function (updatedTemplate: any) {
console.log("Template has been published");
console.log("ETag from server: " + updatedTemplate.etag);
})
.catch(function (err: any) {
console.error("Unable to publish template.");
console.error(err);
});
}
When you are ready to deploy your new function, run the command on your terminal:
firebase deploy --only functions
Now, you can visit your Firebase dashboard and see your functions:
Summary
As an indie developer, it can be hard to keep track of creating a business model, developing an application, answering all the emails and requests from customers, creating marketing campaigns besides all the development stuff. It is important to make use of the tools around us to continue doing a great job.
If you don't know how to write a backend code in terms of creating good Web APIs, securing your services, securing and maintaining your host machine you can use Firebase as a backend solution.
You can directly use Real-Time Database, Remote Config, and Cloud Storage via Firebase mobile SDKs.
You can get rid of all the Firebase dependencies in your app by creating an abstraction layer using Firebase Cloud Functions and calling your functions via a REST interface. Also, you can create cronjobs by using Firebase Cloud Functions.