Development and production config on a trigger.io app - mobile

Our mobile app communicates with a back end API. We want to be able to query a staged copy of the back end during development, and the live version during production.
We need to be able to dynamically configure our app to query stage.example.com during development, and example.com during production.
How can I easily manage these configuration parameters using Trigger.io forge?

One way to do this would be to use our parameters module
This would let you pass a flag into your code at build time which your JavaScript could then use to vary its action e.g.
In config.json:
{
"modules": {
"parameters": {
"production": false
}
}
}
In your JavaScript:
if (forge.config.modules.parameters.production) {
server_url = "example.com";
} else {
server_url = "staging.example.com";
forge.enableDebug();
alert("Set production flag to true before packaging!");
}

Related

Can any React app be deployed to Netlify?

I am having trouble understanding the concept of static and dynamic sites within the context of a React app. I am reading about how you can deploy React apps to Netlify which is known for hosting static sites. But all the React apps I've made make requests to Node/Express backends and shows the data that gets returned from them. I'm pretty sure that would make my React apps dynamic. Does this mean that I wouldn't be able to deploy them to Netlify?
You would be able to host the frontend part on Netlify that makes request to a backend elsewhere. But you won't be able to host the backend on Netlify, unless you convert it into serverless functions.
let api = ""
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
//production
API = "https://project-sprint.herokuapp.com";
} else {
//development
API = "http://localhost:3001";
}
/
/ after i concat endpoint complement with this base, then no problem when i deploy

How Do I Configure REST Urls When Running React With Azure API-Management?

I have a reactjs front end that gets data from a spring boot backend via rest calls.
Running locally the code for this looks like:
axios.defaults.baseURL = 'http://localhost:8080/api';
axios.get('/devices').then((resp) => {
this.setState({devices: resp.data});
}).catch(() => {
console.log('Failed to retrieve device details');
});
When I build the code to deploy with npm run build I still have localhost as the url.
How do I build it so that developing locally it uses localhost but deploying it uses a different url?
Once I am in Azure I will have one front end and multiple back ends that need to be pointed to depending on who is logged in.
How do I configure the API-Management layer to route the calls to the correct back end depending on who is logged in (using AD for auth)?
Since I am using APIM for the routing, what should the baseURL be?
Manage those variables in a config file and load based on the environment.
Local Values
you can hardcode local variable directly in a config file
Production Values
- keep place holders and set them from build pipeline or
- hard code them also
E.g:
config.js
const serverVars = {
authUrl: '#{authUrl}#',
apiUrl: '#{apiUrl}#',
};
const localVars = {
authUrl: 'local_auth_url',
apiUrl: 'local_api_url',
};
export function getConfiguration() {
if (process.env.NODE_ENV === 'production') {
return serverVars;
}
return localVars;
}
when you call apiUrl
import axios from 'axios';
import { getConfiguration } from 'config';
axios.defaults.baseURL = getConfiguration().apiUrl;
One approach can be using environment variable. You can have different url based on the environment variable.
Another way is just removing the domain from base url, but this will work only when your backend and frontend domain & port are identical.

Running Firestore local e.g. for testing

Is there a way to run firestore locally (e.g. for testing purposes)?
What would the approach to write tests against the DB (except of using mocks)
Update 2020:
There's now also a Firebase Emulator Suite.
Update Nov 2018:
Local emulation, at least for the purpose of testing Firestore rules, was demoed at Firebase Summit 2018 using #firestore/testing and documented under Test your Cloud Firestore Security Rules.
It looks like it's along the lines of:
const firebase = require(`#firebase/testing`)
const app = firebase.initializeTestApp({
projectId: 'my-project',
auth: { uid: '123', email: 'name#domain.com' }
})
const attempt = app.firestore()
.collection('colId').doc('docId').get()
firebase.assertFails(attempt)
firebase.assertSucceeds(attempt)
It seems early-on, as it's not been noted in the release-notes, but I'm sure it's coming along.
There is not currently, but stay tuned as it's something we want to provide.
In the meantime we suggest uses a separate testing project to cover this. The daily free tier per project helps with this too.
You can run the Firestore emulator by running:
gcloud beta emulators firestore start
and then set the FIRESTORE_EMULATOR_HOST environment variable as per the console output (e.g. run export FIRESTORE_EMULATOR_HOST=::1:8505).
This requires the Google Cloud SDK and a Java 8+ JRE installed and on your system PATH.
for a firestore testing write a js example test.js
you could test write with this format example
var data = {
value: {createTime: new Date(),
updateTime: new Date(),
fields:{
name:{stringValue:'new value data'},
age:{integerValue:50}
}
},
oldValue: {createTime: new Date(), //old create time
updateTime: new Date(), //old update time time
fields:{
name:{stringValue:'olvalue data'},
age:{integerValue:50}
}
}
};
testFireStoreEvent(data);
for run execute
firebase experimental:functions:shell < test.js
UPDATE!!!! VALID FOR WRITE AND UPDATE EVENTS
var data = {
before: {
//your before data
},
after: {
//your after data
}
};
testFireStoreEvent(data);
There are two libraries which attempt to facilitate mocking of the firebase sdk.
1) https://github.com/soumak77/firebase-mock
2) https://github.com/mikkopaderes/mock-cloud-firestore
I currently use the first one, since it seems to have a bit more of the SDK implemented.
They're not perfect, but they're currently sufficient for my needs, and are preferable to the other approaches since they're entirely in-process.
Note that firebase-mock (#1) does cause a webpack error if used as-is from Webpack/web code. To resolve, you can use option #2 (mock-cloud-firestore), or use the workaround mentioned here (until a fix gets merged): https://github.com/soumak77/firebase-mock/issues/157#issuecomment-545387665
Other options:
3) Firestore emulator: needs the google-cloud-sdk, and relies on a separate process
4) Separate test project: relies on connection to the internet, which also means possible quota limitations/costs
5) firebase-server: Only supports the realtime-database api, not Firestore
Firestore can be setup in local using gcloud.
Start the firestore emulator by running gcloud beta emulators firestore start --host-port=localhost:8081 and if it started successfully you will be seeing Dev App Server is now running
In case if you are using #google-cloud/firestore then create the Firestore instance in this way
// Firestore instance only for test env
const { Firestore } = require('#google-cloud/firestore')
const instance = new Firestore({ projectId; 'Your project id', host: 'localhost', 'port': 8081})
Now you have an option to work with local firestore emulator by setting local host:
var db = firebaseApp.firestore();
if (location.hostname === "localhost") {
db.settings({
host: "localhost:8080",
ssl: false
});
}
https://firebase.google.com/docs/emulator-suite/connect_and_prototype#instrument_your_app_to_talk_to_the_emulators

How to parameterize variables in a React Webpack app for different environments?

I'm working on a React web app which was created by create-react-app and I am getting ready to deploy it.
The issue is, for development, the app uses the api instance running on my dev environment (localhost:{api-port}) but for the deployed app this should point to the server api instance (api.myapp.com).
Currently the host is just a variable in my networking component:
const hostname = 'localhost:9876'
I plan on using webpack to generate the static files which will be served by the production front-end, and I would like to continue developing using npm start as set up by create-react-app.
What would be the correct way to set up my project such that the host can be set automatically to the correct value based on whether I'm running the dev server or building for production?
A common solution is to check against process.env.NODE_ENV like this:
const hostname = process.env.NODE_ENV === "development" ? "localhost:9876" : "localhost:6789";
You may need to force the environment variable to be present in your Webpack configuration file using the DefinePlugin like this:
plugins: [
new webpack.DefinePlugin({
"process.env": {
NODE_ENV:JSON.stringify(process.env.NODE_ENV || "development")
}
})
]
An alternative solution might be to use the config package and provide your hostname string as a configuration parameter. config will inherit configurations from files based on the current NODE_ENV. It will start by using configuration from a default.json file, then override it with a development.json, or production.json, depending on your environment.
Note that you'll need for the config files to be copied to your output directory using CopyWebpackPlugin for it to work.
There are definitely many ways you could achieve that. One of those solutions would be to use webpacks's DefinePlugin. In your plugins section in webpack configuration you would add something like this:
new webpack.DefinePlugin({
API_HOST: process.env.NODE_ENV === 'production'
? JSON.stringify('localhost:8080')
: JSON.stringify('api.com')
}),
That creates a global variable API_HOST available everywhere in your codebase, which you can use. You can read more about the DefinePlugin here https://webpack.js.org/plugins/define-plugin/
you could use a relative path when you make any request to your api server instead of calling the full url for your app.
and for your development you could add a proxy property to your package.json file:
{
...
"proxy": {
"/api/*": {
"target" :"http://localhost:9876"
}
}
}
so whenever you make any request that prefixed with /api will be redirected to http://localhost:9876/api this is just in the development but in the production if you make a request prefixed with /api it won't be redirected it will be served normally because the proxy is just available in the dev server coming with create-react-app.

Different values configuration constants

I have an AngularJS website in different environments (dev, prod). I also have some configuration constants that are different depending on the environment (i.e. to send requests to an API).
I have read many posts that solve this with Grunt by creating a dynamic file. Is there any other "more homemade" approach?
UPDATE
In the client side, Im runnĂ­ng my AngularJS client application in an Nginx web server.
You could make your Node.js server decide which configuration file to serve to your client.
var app = express();
app.set('env', process.argv[2] || 'development');
//...
app.get('/libs/config.js', function(req,res){
var env = app.get('env');
if(env === 'development') {
res.sendfile('config/dev-config.js');
} else if (env === 'production') {
res.sendfile('config/prod-config.js');
} else {
res.send(404);
}
});
And in you angular client you do:
<script src="libs/config.js"></script>
And your servers you run your node doing
node app.js development
node app.js production
Also, I think Express has direct support to configure your current environment using process.env.NODE_ENV, so most likely, all you have to do is to set the NODE_ENV=production environment variable in your production Node.js server and you won't need to pass the configuration from the command line directly.
This is a hack, but my home made approach is to override the address of my API using a static hosts entry.
/etc/hosts
192.168.1.100 api.mydomain.com
It is dirty but it works.

Resources