Experimenting in Supabase

I happened upon an article listing open source projects that mentioned Supabase. They described it as an alternative to Firebase, and that caught my attention. Not too long after, I had a bunch of pictures to organize, so I thought I’d give it a try for that project.

Here are my notes on getting the project started.

Creating the Project

To start, I created an account on the supabase login page. I’m just using it in the cloud. I clicked the sign up link, and it used my GitHub account as the login authentication.

Once signed in, I clicked the green “Create Project” button.

After selecting an organization, that brought me to the Create project screen:

It took it a minute to build things and set them up…

I didn’t time it, but when I came back to it, the screen offered to start me off with a new table in my new database.

Creating a new table gives me the chance to name the table and define the primary key.

Once the table is created, then I can use the New Column button to add my other columns.

I found that I could check my usage by going to Settings > Billing & Usage. Since I only get 2G of file storage and I have 5G of video/photos to organize, I won’t be storing them on supabase itself. I’ll just store the organization info there.

Creating the Flutter App

I decided to start in Android Studio to create my flutter app.

I just walked through the wizard to create the new project:

Running the new app using the “Linux (desktop)” setting, I got the basic application window:

To add the Supabase client, I installed the package with the following command:

flutter pub add supabase

To test how this works, I created a new widget that could read a path value from Supabase. It uses the FutureBuilder widget to call a connect() method that I would write. The connect method will return the path. So, while it is running, it will show the circular progress indicator, and when it is done, it will show the path in a Text widget.

Widget build(BuildContext context) {
  return FutureBuilder(
    future: connect(),
      builder: (context, snapshot) {
      print("Testing ${snapshot.hasData}");
        if(snapshot.hasData) {
          return Text("Path ${snapshot.data}");
        } else if(snapshot.hasError) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              CircleAvatar(
                child: Icon(Icons.warning),
              ),
              Text("Failed ${snapshot.error.toString()}")
            ],
          );
        } else {
          return Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              CircularProgressIndicator(),
              Text("Connecting"),
            ],
          );
        }
      },
  );
}

To get the code to talk to Supabase, I had to find the API Key and the URL. I found it on the API > Authentication page.

So, my dart test method looked something like this:

connect() async {
  print("Connecting ....");
  final url = "https://<redacted>.supabase.co";
  final key = "<redacted>";
  final client = SupabaseClient(url, key);
  print("Connected!!");
}

The only problem is this doesn’t return the path string or even query the Supabase database. So, I added this code in to get the information from my tblComputer table:

Future<String> connect() async {
  print("Connecting ....");
  final url = "https://qpymjxasmfmjknbvtrop.supabase.co";
  final key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYyNDcxOTA5NywiZXhwIjoxOTQwMjk1MDk3fQ.KTFWPJkGLg_gsyu3nPqFl_ry1bhWu3DnrILEDNLTnuo";
  final client = SupabaseClient(url, key);
  print("Connected!!");
  final response = await client
  .from("tblComputer")
  .select()
  .execute();
  print("queried");
  print(jsonEncode(response));

  return response.data[0]["path"];
}

Note: the Supabase client doesn’t have much information about using insert() and delete() methods. But, I did find out that the from() method returns a PostgrestQueryBuilder class.

Resources

Leave a Comment

Your email address will not be published. Required fields are marked *