Building An App to run Linux command and Getting its Output from Firebase

This blog is all about what is firebase and how can we save data inside it and how to get an output from it.

In this article, we are going to see an app that can run a command on the Linux terminal and for that, we use CGI-bin(Common gateway interface). It’s like there is someone in your Operating System who is waiting as soon as you send command it will run particular command. CGI-bin can be written in any language. It is called as server-side language. Here we are using python and we will make this script on AWS cloud instance.

Cgi bin Redhat os can be found under the service of https server that comes under apache.

Lets first set up our API to run a command on Linux OS using CGI

Step1: download httpd server and download python3 if not exist

yum install httpd=> for downloading httpd server

yum install python3=> for downloading python3

Step2: Once installed enable httpd

systemctl start httpd

systemctl enable httpd

Step3: Remember to stop the firewall in Linux OS from the following command.

systemctl stop firewalld

systemctl disable firewalld

The above command should only be used when running this on a local system. If using cloud, then in security group it automatically allows all the traffic.

Step4: Disable Selinux security by using the following command

setenforce 0

Step5: Now go to the CGI-bin folder and make a file with the name. We want here is the file with name input 1.py

Step6: Now once you create a file make it executable using the final command

chmod +x filename

eg:- chmod +x input1.py

Once all the above steps are done, we can go to Android Studio or Visual Studio to build our App.

Here first, we need to go to firebase and create one folder for our app. After that, we need to make one collection. Here I use the date command. One can use any.

Once we are done with setting up firebase, for the app we need some libraries to deploy our app. To install libraries one can install it from pub.dev .

We need the following libraries

firebase_database
cloud_firestore
firebase_core
http

Once we get these libraries, we can paste the lines in the following way to install it in our particular app.

Once we are done with the libraries installation, we are ready to create the application.

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:http/http.dart' as http;

First, write the above code to import all necessary packages we need and define the variables we need.

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
final databaseReference = FirebaseFirestore.instance;

From the above code, we have initialized our app to connect to the firebase and the basic structure is made with an app bar.

class mybody extends StatefulWidget {
@override
_mybodyState createState() => _mybodyState();
}

class _mybodyState extends State<mybody> {
web(cmd) async {
print(cmd);
var url = "http://34.204.37.111/cgi-bin/input1.py?x=${cmd}";
var r = await http.get(url);
print(r.body);
setState(() {
output = r.body;
});

createRecord();
}

void Retrive() {
setState(() {
message = "Be patient we are fetching output";
});
databaseReference.collection("date command").snapshots().listen((result) {
result.docs.forEach((result) {
Future.delayed(const Duration(milliseconds: 4000), () {
setState(() {
message = result.data().toString();
});
});
});
});
}
void createRecord() async {
await databaseReference.collection("date command").doc("result").set({
'output': output,
});
Retrive();
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
TextField(
onChanged: (b) {
cmd = b;
},
decoration: new InputDecoration(
border: InputBorder.none,
hintText: 'Enter host port you want to attach',
suffixIcon: Icon(Icons.search),
contentPadding: EdgeInsets.all(20)),
),
RaisedButton(
color: Colors.blueAccent,
onPressed: () {
web(cmd);
},
child: Text('Execute'),
),
Container(
child: Text(message),
)
],
);
}
}

Now in the above code, one can see three functions web, create a record, retrieve. Let’s understand these three functions since another code is easy to understand if one have basic knowledge of flutter.

Lets first understand the function name web.

web(cmd) async {
var url = "http://34.204.37.111/cgi-bin/input1.py?x=${cmd}";
var r = await http.get(url);
setState(() {
output = r.body;
});
createRecord();
}

Here we have created one variable name URL. Inside it, we are saving the URL of our CGI script we have created and after that output is being saved to the output variable. Once the output from URL is saved in the output variable then they call create record function.

Now let’s understand the function name create record.

void createRecord() async {
await databaseReference.collection("date command").doc("result").set({
'output': output,
});
Retrive();
}

Here we are saving the output in filed output inside the collection name date command and doc name result and once it is been saved in the output field. Then call the function Retrieve.

Now let’s understand the function name Retrieve.

void Retrive() {
setState(() {
message = "Be patient we are fetching output";
});
databaseReference.collection("date command").snapshots().listen((result) {
result.docs.forEach((result) {
Future.delayed(const Duration(milliseconds: 4000), () {
setState(() {
message = result.data().toString();
});
});
});
});
}

In the above code we change the message from output. To Be patient we are fetching output and then the value comes from firebase. We again change the message value. Once got done with this now we can print our message where ever we want.

The final app looks as shown below.

Here is the github repo.

I would like to thank Aditya Gupta with whom I have completed this task.