PocketBill Blog
The account chooser slid up and worked perfectly. What came after it did not, and nothing on screen said so. One cause sat on Google's side — a signing certificate that had never been registered. The other sat in my own code, where a real error was read out of a hook and then never rendered.
PocketBill opens without asking who you are. It is a local-first subscription and bill tracker, so the ordinary week looks like this: no account, no network, a list that lives entirely on the phone. I like that, and I had gone a year without wanting to change it.
Then I moved three years of that list to a new phone, and suddenly an account would have been useful. So I added one sign-in button and tapped it. The system account chooser slid up, clean and correct. I picked my address, and then — nothing. No spinner, no error, no login. The same screen, back where it started.
It is tempting to read that chooser as success. It is not. The picker appearing only means Google recognised the app itself — the package name and the signing certificate matched something on their side. It says nothing at all about the next step, where that picked account is handed over as a credential and has to be accepted.
That next step was failing. The Firebase project for the app had never had a signing certificate registered, and its Android check is unforgiving: if the certificate the device is actually signed with is not on the list, the credential is refused. No exception reaches the UI. The screen simply returns, unchanged, as if the tap had been a thought.
The second cause was mine, and worse. The settings screen called the sign-in hook and pulled three things out of it: the sign-in function, a loading flag, and the error. Then it rendered two of them. The error was read, stored in state, and never drawn. Every genuine failure was therefore dressed as a dead button.
I changed one line to show it in red, then switched to a development build with hot reload so the message would surface without repackaging. The real error appeared immediately, and it named the missing fingerprint outright. A day of guessing had been sitting behind a screen I had written myself.
The fix on Google's side was two fingerprints, not one. The upload key signs what you send for review; Play re-signs it before it reaches a phone, so the certificate the device carries is a different one. Register only the first and the development build works while the shipped one keeps failing — which is exactly the kind of contradiction that eats an afternoon.
Both lessons are cheap to state and expensive to learn. A chooser that opens proves nothing about the step after it. And any login flow that hides its own error becomes undiagnosable in the only build that matters — the one users actually installed.