Building a Post Scheduling App with HarperDB & Flutter

Building a Post Scheduling App with HarperDB & Flutter

Let's learn how to build an app with these two technologies together

ยท

6 min read

Hi everyone, in this article I want to describe my project for the HarperDB Hackathon here on Hashnode. When I saw for the first time the Hashnode Hackathon in collaboration with HarperDB I immediately started thinking about how I can use HarperDB, its services, and APIs.

I look around my needs and I started working on a project to solve one of my problems, that I think other developers on Hashnode also have:

planning posts scheduling and when to share them on other platforms like Twitter, Reddit, Facebook, and LinkedIn

Obviously, I want to create something in Flutter and with the HarperDB API, I connected my HarperDB instance with very simple steps.

Architecture & Functionality

The architecture of the app is very simple, on the database side, there is only one table to store all the posts' schedule info like title, the text of the post on social media, platform, and date of the share. On HarperDB I create a schedule schema and a post table:

harperdb-hashnode-schema-table.png harperdb-hashnode-post-table.png

The JSON that represents the single post schedule is this one:

json-post-schedule.png

There's my Flutter app on the front-end side that lets you retrieve, create, update, and delete all the posts that you have to schedule. By writing the app in Flutter 2.2 you could run the app natively on Android, iOS, and Web. The result is pretty much like this:

mockup-phone-harperdb-hashnode-flutter.png

The posts are ordered by date so you could immediately see what's the schedule. In the app, all the CRUD operations are made in pure SQL as described in the documentation: SQL Operations.

To connect to HarperDB from our app, and the procedure is similar for all other languages and frameworks, you have to use the instance name and the API key, remember to put them in a .env file, and keep away from git by including it on .gitignore. For more information about that you could read these articles:

Code info

As said earlier the app is built with Flutter 2.2 with support for Android, iOS, and Web, and you can find all the code in this GitHub repo: harperdb-hashnode-hackathon with MIT License. The project structure is:

project-structure-harperdb-hashnode-flutter.png

  • models: models to map the table on HarperDB to Dart Class;
  • pages: screens inside the app. The app has only two screens one for the list of the post schedule and one for the single post. I use the same page for the creation and update of a post;
  • repository/schedule_repository.dart: main class to interact with HarperDB API;
  • ui/post_row.dart: personalization of the row of the single post inside the list in the home_page.

To make the project work you need to create a .env file in the project root, that was not added to version control with git, like this:

HARPER_DB_SECRET_KEY='your-secret-key'
HARPER_DB_URL='https://your-istance-name.harperdbcloud.com'

When you run the app, on the homepage you could find the list of all the posts schedule with information on the day, platform to share, title, text, and link to the post. By tapping on a single line you go to the detail page where it's possible to modify all the info, save them to the DB or delete the post scheduling. On the homepage, if you tap on the violet FAB in the bottom right you could create a new post scheduling, and with the refresh button on the top right on the homepage, you sync all the info on the HarperDB with the App.

Models

The post_model.dart is responsible for the translation between the JSON that represents the post schedule and the Dart class, in that class there is the definition of all the fields and the Post.fromJson function converts the JSON from HarperDB in the Post Class used inside the app:

class Post {
  String id;
  String link;
  String platform;
  DateTime postDate;
  String text;
  String title;

  Post({
    required this.id,
    required this.link,
    required this.platform,
    required this.postDate,
    required this.text,
    required this.title,
  });

  factory Post.fromJson(Map<String, dynamic> json) {
    return new Post(
      id: json['id'] as String,
      link: json['link'] as String,
      platform: json['platform'] as String,
      postDate: DateTime.parse(json['post_date']),
      text: json['text'] as String,
      title: json['title'] as String,
    );
  }
}

HarperDB API

All the code to interact with the HarperDB API is in the schedule_repository.dart Class where I create an http.Client and with the flutter_dotenv package I make calls to HarperDB with my HARPER_DB_SECRET_KEY and HARPER_DB_URL. All the functions that correspond to the CRUD (Create, Read, Update, Delete) operations return a Future because are asynchronous and the structure is:

//All calls to HarperDB have been created asynchronously because it is not possible 
//  to know when a response will arrive which is therefore defined as a Future
Future<responseType> actionToPerform(variable) async {
    try {
        //Create a POST request with the http Client
        final response = await _client.post(
            //Set the URL to call
            Uri.parse('${dotenv.env['HARPER_DB_URL']}'), 
            //Set headers like the authentication and the content-type
            headers: {
                HttpHeaders.authorizationHeader:
                    'Basic ${dotenv.env['HARPER_DB_SECRET_KEY']}',
                HttpHeaders.contentTypeHeader: 'application/json'
            },
            //Encode the JSON to send to HarperDB
            body: json.encode({
                //Operation Mode to intercat with HarperDB
                "operation": "sql",
                //Query to execute
                "SQL": "...."
            }),
        );
        //Handle the responde from HarperDB
        if (response.statusCode == 200) {
            return ok_result;
        } else {
            return ko_result;
        }
    } catch (_) {
        return ko_result;
    }
}

Packages

To simplify the development of some functionality, the following packages have been included in the project:

  • datetime_picker_formfield: used to show a datetime picker on the single schedule post to set date and time where to publish the post or share it on social media;
  • flutter_dotenv: used to load configuration variable from a .env file;
  • flutter_styled_toast: used to show a simple toast when the app completes actions like save, update, delete posts;
  • google_fonts: used to customize the look and feel of the app with custom fonts;
  • http: used to make POST requests to the HarperDB API;
  • intl: used to localize and format dates;
  • url_strategy: used to set the web URL strategy, in particular, used to remove the # in the URL of the web app.

Improvements

Obviously, there's a lot of improvement that can be made, I share here some ideas that came to my mind during development, or that were suggested to me, that it could be included in future versions of the application, which for now is to be considered as a proof of concept of what is possible with HarperDB and Flutter:

  • more customization on the UI (like dark mode ๐Ÿ˜‰)
  • better management of app refreshes when switching from one screen to another. Now you have to tap on the update button on the top left of the home page to sync information between HarperDB and the app
  • implement a single post registry and subsequent scheduling by choosing only the date and platform. In this way, you don' have to put the title, link on all the scheduling posts because the registry is unique
  • allow, through a login, multiple users to create their own personal data and then manage their scheduling
  • publish the application on the Android, iOS stores and make it publicly available on the internet. All this is possible directly with Flutter making the application truly multi-platform and available to everyone on any device

An improvement that can be made and that is not directly linked to this app, in particular, is the possibility of developing a package for Flutter to be published on pub.dev with which to interface directly with the HarperDB API in a simpler way and cover the most possible of API calls in the documentation; in this regard, we could certainly establish the discussion directly with the developers of HarperDB to understand if there is interest.

Bye, Alberto

Did you find this article valuable?

Support Alberto Bonacina by becoming a sponsor. Any amount is appreciated!