#30 Firebase as very peculiar limits, or: You don’t want to test in production 🙄

My “user admin” section for poketto.me is quite simple: it lists all registered users, shows when they first (and most recently) used the app, and lets me assign “entitlements” (features like the experimental podcasts and newsfeeds). Works perfectly well on my development instance — but in production, it kept crashing. Turns out: with Firebase, querying documents where a field value is `in` a list of values isn’t very smart — the list may only contain up to **30 (!) values**. ...

July 30, 2025

#28 Capacitor + Android Status Bar = 🤯

The Android status bar (that is, the small bar on top of the screen that shows the current time, the batter status, and notification icons) is really, really weird. It turns out, Capacitor will, by default, make your app a “fullscreen” app: It’ll render your MainActivity (the one that hosts the WebView which in turn hosts your web app) in such a way that the status bar isn’t there at all–on most devices. On some devices, however, the status bar will be visible, but transparently overlay your app 🤨And, to add insult to injury: It’ll change the font color of the status bar to white, so that if you rapp comes with a white background, all the user sees are some weird optical artifacts at the top of their screen. ...

July 28, 2025

#27 You don’t need to bring out the big guns right away (but it’s good to know them anyway)

It’s surprisingly hard to settle on a “fit-for-purpose” technology and tool stack for a modern SaaS / Cloud app. First of all, there are the technical decisions: 🔀 Which frontend, backend, and persistence stack do you use? Angular vs. React, Java vs. Python, Spring Boot vs. Rails vs. Django vs. Flask, MongoDB vs. Firebase vs. MySQL vs. Postgres… 🔀 Do you run it on AWS (Amazon), GCP (Google Cloud), or Azure (Microsoft)? ...

July 27, 2025

#22 GMail’s spam filter is pretty weird

I thought I was being clever when I implemented sign-in via email + one-time token for poketto.me: ✅ No passwords to store ✅ No reliance on external login providers like Google or Facebook And I had two reliable email services to send those tokens: Hetzner, via their all-inclusive web + mail hosting package I’m using for ralphmayr.com, and Zoho Mail, as a lightweight, email-only solution I’m using for poketto.me. On paper, everything looked fine: The SMTP server accepted the mail, and the message was sent. Simple, right? Wrong—especially when Gmail is on the receiving end. ...

July 22, 2025

#21 No, you don’t have to learn LangChain

...or LangGraph, or LlamaIndex, or RAG, or whatever new AI-hype framework is trending this week in order build an AI-powered app. More often than not, these frameworks are just wrappers around basic functionality—in this case, calling an API. And the layers of abstraction they introduce can make even simple things (“prompt an LLM”) feel unnecessarily complex. Take RAG, for example. All it really does is frontload your prompt with additional context. That’s it. In practice, it boils down to concatenating a few strings—something you can do in five lines of code. But LangChain adds layer upon layer of custom methods, config objects, routing logic, etc., that often just get in the way. ...

July 21, 2025

#19 Feedback is key 🔑

Back in my corporate days, I didn’t always give feedback the attention it deserves. But building poketto.me as a solo endeavour has reminded me just how crucial it really is. Working alone has its perks: you can move fast, make bold decisions, and follow your own vision. But it also comes with pitfalls: ➡️ You get blindsided by your own past choices ➡️ You can waste time iterating on suboptimal ideas ➡️ You miss what’s obvious to others ...

July 19, 2025

#18 Socket science isn’t rocket science! 🚀 Or: WebSockets + Flask + SocketIO = ❤️

For some reason, async communication between a web app backend and the browser causes more anxiety than it should (guilty 🙋). I’ve had my fair share of headaches with WebSocket frameworks before, but for poketto.me, I tried a much simpler stack—and was pleasantly surprised: ➡️http backend: Flask ( https://flask.palletsprojects.com/en/stable/) ➡️websocket backend: Flask-Socketio ( https://flask-socketio.readthedocs.io/en/latest/) ➡️websocket frontend: socketio-client ( https://www.npmjs.com/package/socket.io-client) 🔌 Backend: Handling connections is dead simple @socketio.on('connect') def handle_connect(): _, user_id = authenticate() sid = request.sid connected_clients[user_id] = sid 📤 Sending data to a connected client sid = connected_clients.get(user_id)\ if sid: socketio.emit('message', { 'message_type': 'save_changed', 'data': { 'id': save_id, 'state': 'archived' } }, to=sid) #### **🖥️ Frontend: Receiving messages is just as easy** const socket = io(environment.WS_BASE_URL, { ...

July 18, 2025

#17 Designing for mobile after the fact is painful

I’ll admit it: when I built the frontend for [poketto.me, I focused mostly on desktop browsers—except for the reading experience, which was always meant to be mobile-first. But optimizing the rest of the UI for smaller screens later on? A real hassle—and one that could’ve been avoided had I truly embraced mobile-first design from the start. Here are a few key lessons the hard way taught me: 📱 *Thumb-friendly design matters* The Rule of Thumbs is real: ...

July 17, 2025

#16 Material’s tooltip interferes with touch-scrolling on mobile

As I mentioned the other day, I love Angular Material. However, I was quite surprised to discover that the matTooltip directive can negatively impact the user experience on mobile 🤯 I noticed that users couldn’t 'drag to scroll' on poketto.me on their phones (in both the Android app and the browser) when they started to drag particular elements on the screen, such as the save title images. After a lot of analysis and debugging, I discovered that the matTooltip directive, which I use to render tooltips displaying the full save title in case it is abbreviated, sets touch-action: none; on that element. This means: On a mobile device, users can't start scrolling the page with that element as an anchor. It feels totally weird! ...

July 16, 2025

#15 Cloud Build beats GitLab CI for my use case.

When I set up my personal blog, ralphpmayr.com, years ago, I opted for a GitLab CI pipeline to build and deploy it. However, for poketto.me, I was looking for something faster, cheaper and more closely integrated with the Google Cloud ecosystem. I opted for Google's own CloudBuild and discovered that it integrates seamlessly with GitLab.com. In GitLab, all you need to do is create two API keys (one for read access and one for edit access), configure these in Google Cloud and CloudBuild will then be able to fetch and build any GitLab project. ...

July 15, 2025