can i run a node function on a react app directly - node.js

I am making a react app where I need to fetch some data using an API.
I want to deploy this app with Netlify so I cannot use a backend. So, I wrote a Firebase Cloud Function to handle the fetching. However, Google wouldn't allow third-party API requests on the free plan.
So either I have to learn using AWS or I will write a backend and deploy using another service.
Honestly, I don't want to do either. So, my question is, can I call this node function directly inside my react app if so how and is it advisable, if not are there any other alternatives?
The function is something like this:
const functions = require("firebase-functions");
const League = require("leagueapiwrapper");
require("dotenv").config();
exports.getFavorites = functions.https.onCall(async (data, context) => {
try {
const LeagueAPI = new League(process.env.API_KEY, Region.TR);
...
The only thing that actually requires node is the leagueapiwrapper package. (Obviously I will get rid of firebase related stuff).

Related

Is it possible to have a Firebase Function that is triggered by changes to a Firestore that lives in a seperate Firebase project to the Function?

Let's say I have a Firebase project named "A". Within this project, I have a Cloud Firestore triggered Firebase function that needs to run when a document within Firestore changes. By default, the Firebase Function will listen to changes within Firestore on project A.
However, let's say I have a particular use case where there is a second Firebase project named "B". I need the Firebase Function within Project A to be triggered on Firestore changes that happen to Firestore within project B.
Is this possible? Firebase docs do show initializing multiple projects, which would allow me to connect to multiple databases as such:
const admin = require("firebase-admin");
const serviceAccount = require("path/to/serviceAccountKey.json");
const secondaryAppConfig = {
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
};
// Initialize another app with a different config
const secondary = firebase.initializeApp(secondaryAppConfig, "secondary");
// Retrieve the database.
const secondaryDatabase = secondary.database();
But this doesn't allow me to trigger a Firestore Triggered Firebase Function on my secondary project. Firebase functions call the firebase-functions methods directly, whereas calling a database calls the initialized project.
const functions = require('firebase-functions');
exports.myFunction = functions.firestore
.document('...')
.onWrite((change, context) => { /* ... */ });
Is what I would like to do possible? Or does anyone have a workaround (other than creating this Firebase Function within project B)?
It's not possible. Cloud Functions triggers can only fire in response to changes in the resources of the project where they are deployed. This is true for all types of triggers, including Firestore.
If you want code to run in response to changes in another project, the function will have to be deploy to that project.
Currently it is only possible for writes to Cloud Firestore to trigger Cloud Functions that are part of the same project. It is not possible to trigger Cloud Functions that are defined in another project.
The typical solution is for example to call a HTTP Function in the secondary project, for which you can then configure the complete URL.
I'm not sure it can be done all in one codebase - that's from a lack of experience though. I'd say, given your setup, your calling function can trigger your callee function via HTTP call (documentation)
This might require a paid Firebase plan, but I'm not certain of it (source)

How can I deploy a discord.js bot to Cloud Functions?

I want to deploy a Discord bot running on discord.js to Firebase Cloud Functions but I can't get the bot to run in Firebase. If I use nodemon it runs perfectly but if I use firebase deploy it will not start the bot.
Here is my current code:
const functions = require('firebase-functions');
require('dotenv').config();
const token = process.env.TOKEN
const Discord = require('discord.js')
const Client = new Discord.Client();
Client.on('ready', () => {
Client.channels.find(x => x.name === 'main-cannel').send('bot is deployed')
Client.user.setGame(`The Cult | ${Client.guilds.size} servers`)
Console.log('test')
});
Client.login(token);
//is is not working but de basic
//export.App = functions.... {Client}
exports.app = functions.https.onRequest((request, response) => {
response.send("Test");
});
This may not be the best combination of google cloud platform services, since cloud functions where not designed with this in mind. You can just host your Discord bot on a compute engine machine.
If you want to use the dynamic scaling have a look at Discord Microservice Bots where DasWolke describes what microservices are. Hey also included his javascript code to split up the different services for Discord.
What you can do on Google cloud platform specifically, is creating a VM with the Gateway running. This needs to run 24/7 and should be lightweight. You can use an f1-micro (which is free) for this though google recommends a g1-small for the task.
The gateway should filter the events you are looking for (because Discord sends a lot of events and you don't need most) and send the data to cloud function or cloud run (you can send the data via pub/sub). In my experience, a cloud run has much shorter startup times so I went with that.
Inside your function, you receive the data do with it what you want. If you want something in Discord (send a message, manage channels, ...) you can use SnowTransfer for that. SnowTransfer just calls the rest API on discord.
Put client.login(token) into where response.send("Test"); is. This will prompt your bot's code to execute upon an HTTP request.
In https://us-central1-<your project ID>.cloudfunctions.net/app, replace <your project ID> with your project's ID.
If Firebase Hosting gives you the URL example-123.web.app, your project ID is example-123. You can also get your project ID through the console: open the Firebase console, select your project, click the settings icon, go to "Project settings," and its ID is on the second line of the table.
For this to work, you have to move your token straight into the code. You can't use a shell file like .env.
In the end, your code will be:
const functions = require('firebase-functions');
const token = 'whatever the token is';
const Discord = require('discord.js')
const Client = new Discord.Client();
Client.on('ready', () => {
Client.channels.find(x => x.name === 'main-cannel').send('bot is deployed')
Client.user.setGame(`The Cult | ${Client.guilds.size} servers`)
Console.log('test')
});
exports.app = functions.https.onRequest((request, response) => {
response.send("Test"); // Do not delete this! Your request will time out if you do.
Client.login(token);
});
As Gabber235 noted, this is probably not the best Google Cloud Platform service to use for this, and you should probably use Compute Engine.

Firebase functions: koa.js server how to deploy

I already have an app written in MERN stack with koa server prepared build version. My main node file to run by node server.js command to start the whole app looks like this.
In every tutorial, I see that I need to add functions.https.request etc. in the beginning of coding (or at least to suppose doing it).
How could I host my app on firebase the same as I could on heroku - with whole server side?
It is possible to host Koa app using firebase functions, I figure it out after some Googling and analyzing.
This is a piece of code from my project, it is now hosted with firebase functions:
const Koa = require('koa');
const app = new Koa();
// ... routes code here ...
// This is just for running Koa and testing on the local machine
const server = app.listen(config.port, () => {
console.log(`HITMers-server is running on port ${config.port}`);
});
module.exports = server;
// This export is for Firebase functions
exports.api = functions.https.onRequest(app.callback());
You can see the docs and tutorial video for more information.
By the way, here is another example to deploy Koa to now.sh version 2.
You can actually skip the listen call entirely, and use app.callback().
This seems to make more sense than listening on a random port that never actually gets hit.
const functions = require('firebase-functions');
const app = new Koa();
... // set up your koa app however you normally would
app.use(router.routes());
module.exports.api = functions.https.onRequest(app.callback());
You can run an express application using firebase hosting to serve dynamic content via firebase functions. You cannot, however, use Koa.js currently. The functions.https.onRequest requires you to pass an HTTP request handler or an express app returned from express().
Here is the relevant article from Firebase about serving dynamic content from functions.
https://firebase.google.com/docs/hosting/functions
Here is a video tutorial from Firebase on using express.
https://www.youtube.com/watch?v=LOeioOKUKI8
To anyone looking for koa Google Cloud Functions, Here is my working version in typescript
import Koa from 'koa';
import Router from 'koa-router';
import type { HttpFunction } from '#google-cloud/functions-framework/build/src/functions';
const app = new Koa();
const port = process.env.PORT || 3001;
const router = new Router();
router.get('/', async (ctx) => {
ctx.body = 'Hello World!';
});
app.use(router.routes());
// For development on local
if (!isCloudFunctions()) {
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
}
export const helloWorldApi: HttpFunction = app.callback();
function isCloudFunctions(){
return !!process.env.FUNCTION_SIGNATURE_TYPE;
}
For deployment:
gcloud functions deploy test-koa-function --entry-point=helloWorldApi --runtime nodejs16 --trigger-http --allow-unauthenticated
You can't deploy and run an arbitrary node app on Cloud Functions. You have to make use of the different types of triggers that are defined by the product.
See the Cloud Functions for Firebase main page to see the list.
Cloud Firestore Triggers
Realtime Database Triggers
Firebase Authentication Triggers
Google Analytics for Firebase Triggers
Crashlytics Triggers
Cloud Storage Triggers
Cloud Pub/Sub Triggers
HTTP Triggers

Google Cloud Functions, Node JS 8.9.x (LTS) and KOA library

How can I use Koa library, the express replacement, in Cloud Functions?
I know KOA use all great ES2017 and make more use of Async use of JavaScript.
or it might not be needed at all working with Cloud Functions because the Firebase system won't send multiple calls to the same Cloud Function until it ends the previous one?
it unclear to me.
it know demands Node 8.x and I know the NodeJs 8.9.x, has now LTS.
Reading from cloud functions doc:
Base Image Cloud Functions uses a Debian-based execution environment
and includes contents of the gcr.io/google-appengine/nodejs Docker
image, with the Node.js runtime installed in the version, specified
above:
FROM gcr.io/google-appengine/nodejs
RUN install_node v6.14.0
To see what is included in the image, you can check its GitHub
project, or pull and inspect the image itself. Updates to the language
runtime (Node.js) are generally done automatically (unless otherwise
notified), and include any changes in the definition of the base
image.
And I saw a pull request back in November 2017, adding Nodejs v8. Here's hoping it can finally land in Google Cloud Functions 🤞🏻
UPDATE: Google Cloud Functions now support Node.js 8 and even Python!
Referring to the release notes from Google... Cloud Functions Release Notes
Node version supported is still at v6, same for firebase. You need to wait awhile before they release it in v8. Am pretty sure they will move to v8 when v6 no longer supported, but hopefully earlier...
Use babel:
index.js:
----------=
'use strict';
require('#babel/register')
require('babel-polyfill')
const http = require('http')
const createApp = require('./app/app.js')
const handle = createApp().callback()
if (process.env.IS_LOCAL_DEPLOYMENT) {
// to use same code in local server
http.createServer(handle).listen(3000)
} else {
module.exports.http = (request, response) => {
handle(request, response)
};
}
app.js:
--------
'use strict';
const Koa = require('koa')
module.exports = () => {
const app = new Koa()
app.use(......)
return app
}
package.json
------------
"scripts": {
.
.
"start": "export IS_LOCAL_DEPLOYMENT=true && node index"
.
.
}
I just saw in Cloud Functions Console editor for one of my functions that Node 8 is now a runtime option. See screenshot:

How to use Firebase Database in Google Actions?

I'm new to programming Actions for Google Home/Assistant.
I have been using the Inline-Editor under Fulfilment lately and it works fine. Now I want to start using the Firebase DB.
As it says const functions = require('firebase-functions'); in the first lines of the Inline Editor I am assuming, that the Database is ready to use?
If so, how do I access it?
Although Dialogflow uses Firebase Functions to let you do inline code-editing, it doesn't sound like it is a full-fledged Firebase environment. There may be APIs on the back-end that are not setup.
The Dialogflow In-line Fulfillment is meant for simple logic testing and simple operations.
Fortunately - it isn't difficult to take that code and expand it into code that you write... and still host on Firebase Functions! See https://firebase.google.com/docs/functions/get-started for the tools you'll need to install to get started.
For a more extensive tutorial about writing Firebase Functions that work with Dialogflow and getting started with Firebase Functions, you can take a look at the codelab from Google at https://codelabs.developers.google.com/codelabs/assistant-dialogflow-nodejs/index.html
You can use the Google Realtime Database package firebase-admin
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
const db = admin.database();
const ref = db.ref("/");
And to set a value in the database
ref.set({yourKey: 'value'});

Resources