Linux CLI App integrating Firebase

Linux CLI App integrating Firebase

No alt text provided for this image

Have you ever imagined having your remote system handled using an app and moreover it will store all the command and their output on Firebase firestore database?

What we will be seeing?

  1. Integrating your Linux VM with the App over the network using API.
  2. Integrating Firebase firestone with App to save the data with command and it's output.

The functionality of the App:

  1. The user enters the command to be executed.
  2. On pressing the execute button via API the command will be executed and according to the return code(error or status code) it will be sent back to the app.
  3. From the app, data will be first uploaded to the database dynamically with one unique ID.
  4. From there it will be fetched and displayed in the SnackBar of the app.

Firebase

Go to the link to create a firebase account which will be free. Then create a project and here it will ask for the app domain name which you can find from the app-level Gradle file.

No alt text provided for this image

Then it will show some steps to follow along which you need to perform and it's self-explanatory there. In this process, they will provide one file named google-services.json which is a very important file as it helps the app to connect with the firebase. So don't share this file with anyone else. In my Github, I haven't uploaded this file, you have to attach your file. Paste that file in /android/app/ folder.

API

We have to create the API which will take the command and execute it and return the value accordingly. API is basically an interface where the user without authentication can access the system. We have used the HTTP cgi-bin for handling this. So create a file inside the /var/www/cgi-bin which can execute the command. For me, I have my container.py file in the directory /var/www/cgi-bin/linux/create/

command.py

#!/usr/bin/python3
	import cgi
	import subprocess
	print("content-type: text/html")
	print()
	cmdinput= cgi.FieldStorage()
	cmd= cmdinput.getvalue("a")
	output= subprocess.getstatusoutput("{0}".format(cmd))
	

	if output[0] == 0:
	    print(output[1])
	else:
	   
        print(output[1][5:])

APP

Here the main task is to connect with the database and store the data and then retrieving it and showing it through SnackBar. SnackBar is like a toast but an interactive toast, by interactive I mean that we can give actions in the SnackBar and that we cannot do in Toast.

To get the code, follow my GitHub and if you like it please start it GitHub.

I have made different files for all the functionality of the app to have better handling and code management. We mainly have to focus on linuxui.dart and api.dart file.

In linuxui.dart the main logic or the crux resides in the Execute on pressed button which I will be explaining.

api.dart is having the function which will help the app to communicate with Linux VM, for me the VM is rhelv8.

linuxui.dart

Inside this code file, we have to focus on this snippet for understanding how the data update and retrieval work.

No alt text provided for this image

Store in database:

?
WidgetsFlutterBinding.ensureInitialized();
                      Firebase.initializeApp();
                      var fs = FirebaseFirestore.instance;
                      var uuid = Uuid();
                      var ex = uuid.v1();
                      var snack = await linuxcommand(command: _command);
                      fs.collection("command").add({
                        "cmd": _command,
                        "data": snack,
                        "exno": ex,
                      
});

This will help us send the data into the database with a unique ID. We need this ID because we have to fetch the same output from the database and show it in the app. We first need to initialize the widget and then firebase. Now, we are connected and form a collection with name command and inside it, we will store three things, command, data, execution number(unique ID).

Retrieve from the database and showing it in the app:

fs
                          .collection("command")
                          .where("exno", isEqualTo: ex)
                          .get()
                          .then((value) => {
                                value.docs.forEach((element) {
                                  Scaffold.of(context).showSnackBar(SnackBar(
                                    content: Text(element.get('data')),
                                    elevation: 5.0,
                                    shape: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(10),
                                    ),
                                    action: SnackBarAction(
                                        label: "Close", onPressed: () {}),
                                  ));
                                })
                              
});

Here we are first collecting the data from the collection which matches the same execution number which we set and represent it in the SnackBar with an action of close which on pressed will close the SnackBar. Every time a new command is executed the previous SnackBar will automatically be revamped and the new one will be poped.

Finally, our app is ready and good to go!

GitHub: link

Thanks for reading this article and if you have any suggestion or queries fell free to connect with me


Shubham Bhalala

Data Scientist @System2 | MS Data Science @Columbia University | Data Science, MLOps Engineer

4 年
回复

要查看或添加评论,请登录

Shubham Bhalala的更多文章

社区洞察

其他会员也浏览了