Wednesday, 9 July 2025

🎤 Trippingly: A Modest Attempt at Speech Practice Assistance 🗣️

 Right then. Ever found yourself, perhaps, a tad tongue-tied? Or just thinking it might be useful to have a digital companion for those speech practice sessions? Well, Trippingly is my current endeavour in that very direction. It's an application intended to streamline the process of preparing and, in due course, analysing one's verbal deliveries.

This document serves as a rather straightforward guide to getting Trippingly up and running. Whether you're contemplating a contribution, simply curious to see how it ticks, or even just looking for a reference for future self, you should find what you need here.

Progress Report: What's Been Done So Far

We've managed to lay some of the groundwork, establishing the basics for Trippingly. Here's a brief rundown of the current capabilities:

User Management: Basic register and login functionality is in place, handled by Firebase Authentication. Standard stuff, really.

Speech Ingestion: One can now upload speech texts, currently as .txt files. These are then tucked away securely in a personal Firestore collection.

Content Listing: Once a speech has been successfully uploaded, it'll appear in a list on your dashboard. Quite convenient, one hopes.

Detail View: Clicking on a speech entry now takes you to a dedicated page, allowing for a full perusal of the content. No more awkward truncations.

List Synchronisation: The dashboard's speech list now updates itself automatically after a new upload. No manual refresh required, which is nice.

<b>The Technical Bits: A Brief Overview 🛠️</b>

For those interested in the underlying plumbing, Trippingly is built upon a fairly standard modern web stack:


Frontend:React: For building a dynamic and responsive user interface.
Vite: Our blazing-fast build tool for a snappy development experience.
React Router DOM: For seamless navigation between different pages in the app.
Backend:Firebase Cloud Functions: Our serverless backend, running Node.js. This is where our API endpoints live (e.g., handling uploads, fetching speeches).
Express.js: A minimalist web framework used within our Cloud Functions to organize our API routes.
Database:
Firebase Firestore: A flexible, scalable NoSQL cloud database that stores all our user data and speech content.
Authentication:
Firebase Authentication: Handles all user registration, login, and session management securely.

Getting Trippingly Up and Running (For You!)

Ready to get your hands dirty? Follow these steps to set up Trippingly on your local machine.

Prerequisites: The Essentials

Before we begin, make sure you have these installed:

  1. Node.js & npm: Download and install from nodejs.org. We recommend an LTS version.
  2. Firebase CLI: If you don't have it, install it globally:
    Bash
    npm install -g firebase-tools
    
    Then, log in to Firebase:
    Bash
    firebase login
    

Step 1: Clone the Repository

First things first, grab the code!

Bash
git clone https://github.com/your-username/Trippingly.git # Replace with your actual repo URL!
cd Trippingly

Step 2: Set Up Your Firebase Project

This is crucial! Trippingly needs a Firebase project to connect to.

  1. Create a New Firebase Project: Go to the Firebase Console and click "Add project." Follow the steps to create a new project (e.g., trippingly-dev).
  2. Initialize Firebase in Your Project: Navigate to the root of your cloned repository:
    Bash
    firebase init
    
    • When prompted, select:
      • Firestore: To set up your database.
      • Functions: To set up your backend.
    • Choose Use an existing project and select the Firebase project you just created.
    • For Firestore rules: Accept the default file name (firestore.rules).
    • For Functions: Accept the default language (JavaScript). Choose npm as the dependency manager. Do not install dependencies at this point (we'll do it manually for the backend folder).
  3. Set Up Firebase Functions Directory: Ensure your functions code is correctly linked. If firebase init didn't place them in backend/functions, you might need to adjust. For this project, assume backend/functions is where the functions code resides.
  4. Create a Service Account Key (for Local Testing with Emulators)
    • Go to your Firebase Console.
    • Navigate to Project settings ⚙️ > Service accounts.
    • Click "Generate new private key". This will download a JSON file (e.g., your-project-id-firebase-adminsdk-xxxxx-xxxxx.json).
    • Rename this file to serviceAccountKey.json and place it in your backend/functions directory. DO NOT commit this file to GitHub! Add serviceAccountKey.json to your .gitignore in the backend/functions folder.

Step 3: Configure Database & Security Rules (Firestore)

Your Firestore needs rules to allow your Cloud Functions to read/write, and your frontend (if directly accessing Firestore, which we're not for data fetching) would also need them.

  1. Open backend/firestore.rules (or firestore.rules in your project root, depending on your firebase init setup).

  2. Update your Firestore rules to allow authenticated users to manage their own speeches subcollection. Replace the contents with:

    Code snippet
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        // Allow read/write for user documents, if you had them
        // match /users/{userId} {
        //   allow read, write: if request.auth != null && request.auth.uid == userId;
        // }
    
        // Rules for speeches subcollection
        match /users/{userId}/speeches/{speechId} {
          allow read, write: if request.auth != null && request.auth.uid == userId;
        }
      }
    }
    
  3. Deploy your Firestore rules:

    Bash
    firebase deploy --only firestore:rules
    

Step 4: Backend (Cloud Functions) Setup

Now, let's get your serverless backend ready.

  1. Install Dependencies: Navigate into your backend/functions directory and install Node.js dependencies.
    Bash
    cd ~/Documents/fun/git_repos/Trippingly/backend/functions
    npm install
    
  2. Deploy to Live: For your Cloud Functions to work live, you need to deploy them. This step is only needed if you want to test against live functions (and is often done once you're ready for production testing).
    Bash
    firebase deploy --only functions
    
    • Note down the base URL provided in the output for your api function (e.g., https://us-central1-your-project-id.cloudfunctions.net/api). You'll need this for your frontend if you test live.

Step 5: Frontend Setup

Next, configure your React app to talk to your backend.

  1. Install Dependencies: Navigate into your frontend directory and install npm dependencies.

    Bash
    cd ~/Documents/fun/git_repos/Trippingly/frontend
    npm install
    
  2. Create .env file: In your frontend directory, create a new file named .env. This file stores environment variables that Vite (your build tool) will expose to your React app.

    ~/Documents/fun/git_repos/Trippingly/frontend/.env

    Code snippet
    # Example for local Firebase Emulators:
    VITE_CLOUD_FUNCTION_URL="http://localhost:5001/YOUR_FIREBASE_PROJECT_ID/us-central1/api"
    
    # Example for deployed Cloud Functions (uncomment and use when deploying to production):
    # VITE_CLOUD_FUNCTION_URL="https://us-central1-YOUR_FIREBASE_PROJECT_ID.cloudfunctions.net/api"
    

    Replace YOUR_FIREBASE_PROJECT_ID with your actual Firebase project ID! (e.g., trippingly-dev). Keep the localhost URL uncommented for local development.

Step 6: Running Trippingly Locally!

You're almost there! It's time to fire up both your frontend and backend.

  1. Start Firebase Emulators (Backend): Open a new terminal window. Navigate to your backend directory:
    Bash
    cd ~/Documents/fun/git_repos/Trippingly/backend
    firebase emulators:start
    
    Wait for "All emulators ready!"
  2. Start Frontend Development Server: Open another new terminal window. Navigate to your frontend directory:
    Bash
    cd ~/Documents/fun/git_repos/Trippingly/frontend
    npm run dev
    
    This will give you a local URL (usually http://localhost:5173).

Now, open your browser and go to http://localhost:5173! You should see the Trippingly app. You can register, log in, upload speeches, see them in the list, and click on them to view full details!

A Peek Behind the Curtains (High-Level Architecture)

Here's how everything dances together:

  • Your React Frontend serves the user interface.
  • When you upload a speech or fetch your speech list, the frontend makes API calls (using fetch) to your Cloud Functions (the Express.js app).
  • The Cloud Functions, after authenticating your request using your Firebase ID token, interact with Firestore to store or retrieve speech data.
  • All user accounts are managed by Firebase Authentication.

What's Next for Trippingly?

Our journey is just beginning! Future features include:

  • Unit & Integration Testing: Building a robust test suite to ensure everything stays bug-free. (You're looking into this next!)
  • Speech Playback: Text-to-speech for practicing your delivery.
  • Speech Analysis: Providing insights on pace, filler words, and more!
  • Editing & Deleting Speeches: Managing your content.

Get Involved!

Feel free to explore the codebase, open issues, suggest new features, or even contribute. Trippingly is a passion project, and we're excited to see where it goes!


How does that look? It covers the main setup points in a step-by-step manner. Let me know if you'd like any additions or tweaks!

Friday, 18 April 2025

I kept going so here's a reminder for next time I've been away from the project for 2 years

🦄 Project Log: Upgrading My Unicorn Text Project (April 2025)

🚀 Overview

This project connects a Pimoroni Galactic Unicorn Pico W to a Google Cloud Platform (GCP) serverless API that controls the scrolling text remotely.

  • Backend: Node.js, Express.js, Firestore (GCP)
  • Frontend: Simple HTML/JS (eventually!)
  • Deployment: Cloud Run with Cloud Build
  • Security: Bearer Token Authorization + Secret Manager
  • Storage: Firestore Database

🛠️ Main Changes and Improvements

1. Local Pico W Development Setup

  • Installed mpremote for flashing and file management.
  • Created a deploy.sh script to easily push code to the Pico.
  • Setup .env secrets for WiFi credentials and server URLs.
  • Used Micropython firmware.
  • Created a pretty console output when deploying.
  • MicroPython Docs

2. Backend (Cloud Run API) Improvements

  • Split project into app.js (Express app) and server.js (listener).
  • Why split app.js and server.js?
  • Proper CORS setup to allow frontend to talk to backend.
  • Centralized Firebase Admin SDK initialization (utils/firebase.js).

3. Firestore Data Improvements

  • Structured Firestore documents to include:
    • text (display text)
    • updatedAt (server-side timestamp)
    • updatedBy (who set the text)
  • Logged every update into a Firestore subcollection history.

4. Secrets Management (Security)

  • Switched from environment variables to GCP Secret Manager.
  • Fixed service account permissions for secrets access.
  • GCP Secret Manager Docs

5. Frontend Changes (WIP)

  • Created a basic frontend for text updates.
  • Handled CORS properly.
  • Added Bearer Token headers to secure API requests.

📋 Final Tech Stack Overview

  • Hardware: Pico W (Galactic Unicorn)
  • Firmware: MicroPython
  • Local Dev Tools: mpremote, VS Code
  • Backend: Node.js, Express, Firestore
  • Authentication: Bearer Tokens
  • Secrets: GCP Secret Manager
  • Hosting: Cloud Run (serverless)
  • Database: Firestore (NoSQL)
  • Frontend: Basic HTML/JS

📚 Key Links for Future Reference


🧠 Lessons Learned

  • CORS must be handled before mounting routes.
  • Always explicitly initialize Firebase Admin SDK.
  • Structured Firestore data makes future features easier.
  • Logging to console and audit trails are essential for debugging.

🚀 Future Ideas

  • Add /history API endpoint to view full update logs.
  • Prettify the frontend to show timestamps and usernames.
  • Setup OAuth login instead of bearer token for future users.
  • Deploy frontend separately (Netlify, Firebase Hosting).
  • GitHub Actions for auto-deploy on commit.

🦄 Final Thoughts

This is no longer just a toy project — it's a scalable, secure, audit-logged cloud-connected Unicorn 🦄 system! With a real API, real secret management, history tracking, and easy extensibility — Ready for next steps whenever I pick it back up again!

Returning to the Unicorn

Building a Smooth Workflow for Raspberry Pi Pico W Projects with VS Code and mpremote

This morning I decided to tackle a nagging issue: my Raspberry Pi Pico W development workflow felt clunky. Uploading code manually, dealing with VS Code IntelliSense errors, and fiddling with board resets slowed me down.

I wanted a press one button, everything works experience.
Here’s exactly what I did to streamline my setup — and where I’m heading next.

Tuesday, 9 October 2018

And slowly we get worse...

So this timelog project started as a simple zsh script:

function timelog() {
if [ "$1" != "" ]
then
echo $(date +%H:%M) "$1" >> ~/timelogger/$(date +%Y-%m-%d).txt
fi
}

This created a new file if one didn't exist called <<date>>.txt (for example 2018-10-09.txt) that would then put whatever details were passed to it into it.
This had several advantages over what I've got to now, mostly it was nice and easy to edit.

With the changes I'm now making it does appear that I'm getting further away from where I was.

I've now got just about a graphql server running that just about works to retrieve whatever has been written, but I'm not yet using that to write to, soon, but not yet.

Adding more interesting and fun technology has been it's own reward, but it's not made what I'm working on much more useful (yet).

The git repos for the more confusing bits are here:

Tuesday, 25 September 2018

Adding a pile of issues...

This evening I added a pile of issues to GitHub, and in a shocking turn of events I've managed to fix one of them. By fix one of them I of course mean I found that things already worked that way.

I've also done some tidying up.

Next I want to start getting some unit tests in and then start some unit tests in a TDD style manner.

After that it's to the fun world of Graphql with go. I've found some fun filled exciting blogs about this.

I'm really quite enjoying go.

Monday, 24 September 2018

Keeping going with go

Well another evening of GO, which has been really quite good fun...

I've started moving some things about so that the code has separated a bit better. I had started with some testing, but that wasn't going so well, so that's a plan for next time!

Things that I've got going so far:

  • Working and compiling!
  • Reading config file
  • Connecting to a remote mongo db
  • Writing to a reading from mongo db
  • Reading the passed in parameter
I've also got a whole lot of VS code plugins working.

Go seems to encourage multiple repo's which is a little odd, but I suppose it's nice for encouraging code reuse and other bits, sure I'll get used to it (or start with one and then slowly move things out).

Repo's

Tuesday, 18 September 2018

Trying out a new language.

So about a year ago, my then (and now no longer) boss handed me a book saying you might be interested in this.
That's sat on my desk unopened for almost a year.

The Go Programming Language I've still not opened the book, but I put together a small command line app that could be used to record what I'm doing, while I'm doing it. I'll keep playing I quite like it (so far). If you're interested the repo is here: https://github.com/benjimouse/timelog I'll update with more details later.