Get firebase function url from admin SDK programatically - node.js

Is there a way to get the Firebase Function url from the Admin SDK for nodejs?
In prod it will look like: https://REGION-PROJECT.cloudfunctions.net/FUNCTION_NAME
And when serving locally: http://localhost:PORT/PROJECT/REGION/FUNCTION_NAME
Is it possible to get this value in nodejs programmatically? E.g. from admin or configuration settings?

The Firebase Admin SDK doesn't expose any APIs that deal with Cloud Functions. From what you've shared, it sounds like you have everything you need to build the URL yourself, which is the right way to go.
If you really must use another piece of software, you'll have to dive very deep into the inner workings of the Firebase CLI and figure out how to reuse its code. You'll probably have to look in two places - one for the emulator, and another for deployment. I suspect this is almost certainly not going to be worth your time, since building the strings yourself is pretty straightforward.

Since you don't say exactly what you want to accomplish, I'll just guess that you want your app to be aware of when you're in development vs. production mode.
What I did was to simply write in some checks in my front- and back-end code. For instance, in the browser/web code:
if (window.location.href.toString().includes('localhost:5000')) {
// exhibit desired behavior for emulator
} else {
// exhibit desired behavior for production
}
Depending on how you're calling your node/backend functions, you could pass along the execution context (emulated or production), and use that in the back, too.
It's not perfect, but it's actually streamlined development for me quite a bit. Hope that helps!

Related

"Dependency hell" when using same npm module for both sdk and service itself

I'm currently developing a project in Node JS that uses microservices architecture, in which each service has it's own repository that contains both the code for the service itself (NodeJS express server), and also an SDK file that I publish for other services to use with methods that are available in this service and Typescript definitions.
So for instance I have a users-service that handles all of the user related actions, and a reports-service that handles all of the reports that users can CRUD.
users-service has a method called "deleteUser" that also goes to reports-service SDK in order to delete all of this user reports. On the other hand reports-service uses user-service SDK to "getUserById" for instance. So what happens is that user-service has reports-service-sdk as one of it's dependencies, and reports-service has users-service-sdk as one of its dependencies. Because the SDK is inside the same npm module with the service, I get users-service-sdk as one of the dependencies of users-service.
I thought of separating the SDK with a different package.json file, but I wanted to know if it's the right way to go or am I doing something really wrong in my architecture :)
Thanks.
This sounds like Circular Dependency which as you stated in the title is tough to deal with. Microservices are great but this sort of architecture sounds like a lot of extra unnecessary work without any added benefit.
You should look into running your services/packages/repositories as Cloud functions (or Firebase functions). AWS also has their own solution for microservices architecture. The reason being is each service can communicate with other services by using internal authorized calls or authorized REST API calls --- or you can make them totally public.
The great thing about these Google Cloud Functions is each function is automatically an Express end-point that accepts GET, POST, DELETE, PUT. Or if you use the internal call for Firebase, each function automatically contains relevant context from the frontend (such as the user's authentication details).
You also configure IAM permissions to only allow who and what service you want to be able to execute your cloud functions so that you have full control of permissions.
To answer your questions directly though, I would definitely avoid Package A having Package B as a dependency as Package B has Package A as a dependency. You absolutely can make that work but there's no upside and a lot of downside.
Here's an old thread which covers the topic.

Is it nonsense to not use Amplify API (and use the AWS API Gateway SDK instead)?

i would like to know if i am the only one thinking to not use Amplify's API and instead use the classic SDK. The reasons are
1st: I am a beginner to AWS and development so the fact that Amplify is hiding the complexity isn't helping me to learn what's going on behind the scenes, control and understand everything well.
2nd: Can i modify the API without changing the generated to local project files? (files that generated while running "amplify add auth" command.
I am very confused about it, and can;t really find a guide of how to modify local files after doing changes to API through AWS platform.

Production Config between Intranet REST server and React Apps

Folks, forgive me if this is a repeat question: I couldn't think of how to phrase it in the search engine. I'm developing an Intranet-based set of applications with the front end (individual apps) in React and the back-end using node.js and Express. I had been using Electron JS but like the Express solution since all web browsers on the Intranet can use the apps.
I'm running into a bit of a circular dependency when it comes to production, though. Since my REST back-end handles all local calls (like node fs) I use REST calls to load and save preferences files from the front end. However, I'd like to be able to set the REST URI from a config file or setting. Since the only way I can access this setting is a call to the REST back-end, I'm stuck. It's possible the client may want to change the host URL and the port for the server. This will affect all axios calls to the REST back end in every React application I have. Instead of calling http://localhost:5000/api-call/ I'd like the localhost and port number to be read from config.
I am transpiling the React apps and storing them in a static folder underneath the REST server. I would like to avoid something complex or additional like REDIS or another local database. My projects don't require any heavy database setups.
Am I simply implementing poor architecture here? I even thought of env variables but then will get into setting them on each client's system which takes away from the flexibility of using a web server in the first place. Any thoughts to move me in the right direction would be greatly appreciated!!!
I knew if I posted this, I might find an answer.
I'm not sure how elegant a solution this is but I could test the env for development vs. production. If in production, I can then use window.href (host and port) to get the information I need. I think this will work but would still love to hear some other thoughts from those with far more experience than I have!

Basic use of server side API and passing server side variable to client side

I've just started my IT degree and I'm a beginner to the use of APIs (and forums like this) so I am truly sorry if my question is to vaguely explained or if it is just plain stupid :), on top of that I'm not a native English speaker :P. Okay, so I'm trying to use Google trends' api which I installed in my server with putty by using sudo npm install google-trends-api. (it can be found here https://www.npmjs.com/package/google-trends-api#installation) As I undestand it, this is a server side api so the scripts that I write with the methods provided for this api will not run on an explorer as normal js files do. There is an example that makes use of the API that I found on the page which is as follows
var googleTrends = requite('google-trends-api');
googleTrends.hotTrends('US')
.then(function(results){
console.log(results);
})
.catch(function(err){
console.log(err);
});
this outputs a list of 20 items on the console when I use it on node.
I would like to know if there is a way to assign those results to a variable and then use that variable in a normal javascript script inside a html file. I do not know anything about node.js and the like, and I would like to actually do some research instead of asking here but I was going to use a different approach to acquire such information but now I've had to change my plans and do not have enough time and given I consider this is a fairly easy problem to resolve (maybe?) I would really appreciate it if someone could walk me through the basics of each step. THanks :) and have a nice day.
Your question is quite broad. Node.js is Chrome's V8 engine bundled with some libraries to do I/O and networking. This enables us to JavaScript outside of the browser and to create backend services or servers in general (in your case). I hope that you are aware of this difference :)
The first thing that you have to do, is to have a look at express.js and to create a simple server. It will not be more than 20 lines of code. Then you have to enrich this with more stuff like a template engine (handlebars.js, jade etc). You have to enable the server to serve static files that will be finally your js, css and image files. Creating this simple server you will be able to serve simple html page in the first place. On top of that you should have the client side javascript that you have to write and now you can use the module above. Unfortunately, you are not able to use this module directly on a javascript file that you will write. To be able to use this module you have to transcompile this thing into javascript that browser understand*. Remember that browser does not understand the require statement and some old browsers possibly will have issues with the promises that this module is using. These are the things that should be compiled. You have to use a tool like browserify for this and the compiled file that this will extract it must be included in the scripts of your html page.
Maybe there are quite a lot of concepts that you are not aware of or you don't understand them but spend a bit of time to understand them.
P.S.: I' ve replied under the assumption that google-trends-api module does not use things that are specific to node.js like the file-system for example.

Application State / Test Fixtures with Xcode UI Tests

A pretty common problem with any kind of integration test is getting the unit under test into a known state -- the state that sets up well for the test you want to perform. With a unit test, there's usually not much state, and the only issue is in potentially mocking out interactions with other classes.
On the other hand, when testing a whole app there's all sorts of potentially persistent state, and getting the app into a clean state, or trickier still, into a known state that isn't "clean" without any access to the app itself is a little tricky.
The only suggestion I've found is to embed any necessary setup in the app, and use something like an environment variable to trigger setup. That is, of course, viable, but it's not ideal. I don't really want to embed test code and test data in my final application if I can avoid it.
And then there's mocking out interactions with remote services. Again you can embed code (or even a framework) to do that, and trigger it with an environment variable, but again I don't love the idea of embedding stubbing code into the final app.
Suggestions? I haven't been able to find much, which makes me wonder if no-one is using Xcode UI testing, or is only using it for incredibly simple apps that don't have these kinds of issues.
Unfortunately, the two suggestions you mentioned are the only ones that are possible with Xcode UI Testing in its current state.
There is, however, one thing you can do to mitigate the risk of embedding test code in your production app. With the help of a few compiler flags you can ensure the specific code is only built when running on the simulator.
#if (arch(i386) || arch(x86_64)) && os(iOS)
class SeededHTTPClient: HTTPClientProtocol {
/// ... //
}
#endif
I'm in the middle of building something to make this a little easier. I'll report back when its ready for use.
Regarding setting up the state on the target app there's a solution. Both the test runner app and your app can read and write to the simulator /Library/Caches folder. Knowing that you can bundle fixture data in your test bundle, copy it to the /Library/Caches on setUp() and pass a launch argument to your application to use that fixture data.
This only requires minimal changes to your app. You only need to prepare it to handle this argument at startup and copy over everything to your app container.
If you want to read more about this, or how you can do the same when running on the device, I've actually written a post on it.
Regarding isolating your UI tests from the network, I think the best solution is to embed a web server on your test bundle and have your app connect to it (again you can use a launch argument parameterize your app). You can use Embassy for that.

Resources