Privacy
What TrainsPh knows
about you, and what it does not
This policy covers the TrainsPh mobile app (com.nico.trainsph,
Android and iOS) and this website, trains.ph. It is written to describe
what the software actually does, rather than to reserve rights we have no
use for.
Effective 5 November 2026 Version 2.2 App TrainsPh 30 Site trains.ph
01 Summary
The short version
There is no account. You never give TrainsPh your name, your email address or your phone number to use the app, and nothing you do in it is attached to a person.
- Finding nearby stations never sends your location anywhere. It is read when you ask for it — on the nearest-stations view, or when you put yourself on the map — compared against station coordinates already on the device, and discarded.
- Sharing your position with other riders does send it, and is off until you turn it on. If you switch on live train positions, the app publishes where you are while you are on a train, so that people waiting at stations ahead can see it coming. It runs in the background while you ride. Starting a trip (Start trip on a fare) also turns it on, for that trip only, after the same explanation and permission, and it switches itself off when the trip ends unless you had turned it on yourself. Switch it off and what you published is deleted immediately. Nothing you publish is attached to a name, because there is no account. While you share, the app also records how long your train took between stations and when it left the start of its run, so that its arrival times and predicted trains improve as people ride; those records are deleted after 90 days.
- Otherwise the only thing the app uploads is a crowd report — a station, a crowding level from 1 to 4, and a timestamp, stamped with an anonymous ID that Firebase issues to the install.
- The app measures how it is used, and you can switch that off. Which screens you open, which fares you look up, which features you use and what goes wrong. It is on when you install the app; the app tells you so the first time it opens, and the switch, in Settings and in About & sources, takes effect immediately. Never your location, never anything you type, never your advertising identifier.
- No crash reporting SDK and no advertising. The app contains no crash reporting library and no ad library, and does not read your advertising identifier.
- Links out of the app open in your browser or maps app. Operator pages, news sources, landmark articles and a station's pin on Google Maps open in the app you already use for that. The only position TrainsPh ever passes along is the station's, never yours.
- No tracking on the website. trains.ph sets no cookies and runs no analytics. The only thing it collects is an email address, and only if you type one into the relaunch form.
- Everything is optional except the fares. Location, live train positions, notifications, crowd reporting and the home-screen widget can each be refused, and the app still does what it is for.
This summary is here for speed, not to replace what follows. Where the two could be read differently, the clauses below govern.
02 Controller
Who is responsible
TrainsPh is built and operated by John Nicholai Villegas, trading as TAIO Labs, in the Philippines. For the purposes of the Data Privacy Act of 2012 (Republic Act No. 10173), that is the personal information controller for both the app and this site.
TrainsPh is a voluntary, independent project. It is not operated by the Department of Transportation, the LRTA, the MRTA, the PNR or any other government agency, and none of them receive data from it.
Questions, requests and complaints go to taioappsdevelopment@gmail.com.
03 The app
What the app collects
An anonymous ID, issued to the install
To share a crowd report, the app signs in to Firebase Authentication anonymously. Firebase issues a random identifier — a uid — to that installation. It is not derived from your phone number, your email, your Google or Apple account, your advertising identifier or any hardware serial, and there is nothing in it or attached to it that names you.
Its only job is to let the server enforce two rules: that a report is stamped with the identity that wrote it, and that one install cannot file more than one report per station every five minutes. Delete the app and the identifier goes with it; a reinstall gets a new one.
Usage analytics
The app uses Google Analytics for Firebase to record how it is used. This is on when you install it, and you can turn it off at any time under Settings → Share usage data or About & sources → Share usage data. The first time the app opens it says so in a strip above the tabs, with the off switch in the strip itself. Switching it off stops collection immediately and is remembered.
What it records:
- Screens — which parts of the app you open.
- Fare lookups — the two stations, the ticket type, whether a concession was selected, how many lines the trip crosses and the fare that was shown. Stations are recorded by their internal identifier, the same one you pick from a list.
- Features used — saving a trip, submitting a crowd report, turning on notifications, saying whether a predicted train was about right (only the line and your answer), and similar.
- Things that went wrong — a data download that failed, a location permission that was refused, a journey that could not be planned. Recorded as a short code chosen by us, never as an error message.
- Language — whether the app is running in English or Filipino.
- Your analytics choice — when you switch collection off, that choice is the last event sent, so we can tell how many people take the option. Switching it back on is recorded too.
- Standard Firebase information — device model, operating system version, country, app version, and an app instance identifier that Google issues to the installation.
What it never records: your location, your advertising identifier, and anything you type. The nearest-stations feature reads GPS and that reading still never leaves your phone; what is recorded is at most the station it resolved to, which is no more precise than picking it from a list yourself.
Analytics data is processed by Google under its own terms. Deleting the app ends collection; the instance identifier goes with it and a reinstall gets a new one.
Crowd reports
When you tap a crowding level, the app writes exactly this:
- Station — which station you are reporting on.
- Level — a number from 1 to 4.
- Time — set by the server, not by your phone.
- The anonymous ID — so the write rules and the rate limit can be enforced.
No text, no photographs, no coordinates. Reports are append-only: nothing in the app or in the database rules permits a report to be edited or withdrawn once written. That is a deliberate integrity property of the crowd data, and it is also why a report contains nothing personal in the first place. The one exception is age — after 90 days the rules permit a report to be deleted, and nothing else.
Live train positions
This is the only feature in TrainsPh that sends your location off the device, and it does nothing at all until you switch it on under Settings → Share live train positions, or start a trip. A trip turns it on for that trip only, after showing you the same explanation and asking the same permission, and turns it off again when the trip ends, unless you had switched it on yourself.
While it is on, the app watches your movement and decides — on your phone, not on a server — whether you appear to be on a train: whether you are following the track of a line, in which direction, and at a speed a train actually runs at. It refuses far more often than it agrees, because a wrong answer puts somebody on a platform waiting for a train that is not coming.
When it agrees, it publishes:
- Your position — latitude and longitude.
- The line, the last station you passed, and which way you are going — worked out on your phone from that position.
- Time — set by the server, not by your phone.
- The anonymous ID — the same one crowd reports use, so the rules can check the row belongs to whoever wrote it.
It publishes roughly every ten seconds while you are on a train, and stops publishing when you get off. Other riders' phones work out how fast the train is going from two of these in a row; no speed is published, and nothing is collected for it beyond the fields above. It publishes nothing while you are walking to the station, waiting on a platform, or travelling any way other than by train.
Why the coordinate and not just the station. The station is what other riders are shown. The coordinate is what lets the app place a train between two stations rather than at the last one it passed, and it is what lets us tell a genuine report from a bad one. We considered publishing only the station, and it makes the feature meaningfully worse at the thing it is for. We have written down what that choice costs you rather than describing it as a smaller change than it is.
Stopping is immediate. Turning the switch off deletes the row you published, then and there — not at the next sweep, and not when it expires. The database rules permit you to delete your own row at any time specifically so that can be true. Force-quitting the app or losing signal also stops it; the row then expires on its own within thirty minutes.
Background location. For this to be useful the app has to keep reading your position while your phone is in your pocket. It does that with "while using the app" permission alone: sharing always starts with the app open, and carries on from there with a notification on Android that shows for as long as it runs, and on iOS the system's own indicator. The app does not ask for your location "all the time".
What is not published. No name, no account, no device identifier beyond the anonymous install ID, nothing you type, and no history. Only your current position, replaced each time and deleted after thirty minutes. We keep no trail of where you have been, and the database is not structured to hold one.
When your train left. Once per ride, your phone also works out when the train you are on left the first station of its run — "an MRT-3 train toward Taft left North Avenue at 08:03" — and records that, with the line, the direction and your anonymous ID. No position and no station. It is how the app learns how often trains really run, so its predicted trains improve as people ride. You have at most one such row per direction per day; a second ride the same way replaces the first. These rows are deleted after ninety days. What is learned from them — a typical gap between trains for each line and hour — is kept and published, with no ID or row in it.
Other things the app learns from rides. While you share your position, the app also records how long your train took between stations and how long it stood at each, and — when you change lines — how long the change took, walk and wait together, as two station names and a number of seconds. After a ride it may ask which side the doors opened; your answer is recorded with the station and direction. Your crowd reports, as before. Each of these is keyed to your anonymous ID and deleted after ninety days. What the app learns from them — typical run times, stops, crowding by hour, door sides, transfer times and the earliest and latest trains riders have seen — needs at least three people to agree, carries no ID, and is kept and published so the app keeps improving.
Device attestation
Firebase App Check asks the platform — Play Integrity on Android, App Attest / DeviceCheck on Apple — to confirm that requests come from a genuine copy of TrainsPh on a real device. This is what stops someone scripting sign-ups to poison the crowd data. Those checks are performed by Google and Apple; the app receives a short-lived token and never sees the device details behind it.
Fare and station data
Every fare, station and travel-time figure ships inside the app, along with service hours, station landmarks and the map's coastline, so the core of it works with no network and no permission at all. On launch the app fetches a small manifest from trainsph-data.web.app and downloads a dataset only if its contents have changed. That is an ordinary HTTPS request, carrying nothing about you beyond what any web request necessarily carries — see who else handles it.
Reporting a wrong fare
If a fare in the app disagrees with what you were charged, the app does not send anything itself. It copies a short template and our email address to your clipboard, and you send the email from your own mail app, if you choose to. What reaches us is exactly what you send — including, necessarily, the address you send it from — and it is used for one purpose: checking the fare and correcting the data. It is the only free text in the app, and it is never an analytics event.
Links that leave the app
The advisories screen links to the operators' own pages — LRMC, the LRTA and DOTr MRT-3 on Facebook, and the news sources an advisory cites. A station's sheet links to Wikipedia for the landmarks around it, and can open the station's position in Google Maps. Every such link opens in your browser or the relevant app, never inside TrainsPh, so nothing you do there passes through us. The map link carries the station's coordinates and name, not yours. Once you are on someone else's site, their privacy policy applies. If nothing on your phone can open a link, it is copied to your clipboard instead.
04 Location
Two different things, and only one of them leaves your phone
TrainsPh uses location for two features. They behave differently and it matters which is which.
Finding the nearest stations — on the device, always
When you open the nearest-stations view, or tap the button that puts you on the map, the app requests a single fix at medium accuracy — stations sit hundreds of metres apart, so metre-level precision would buy nothing and cost battery — and compares it against station coordinates already bundled in the app.
- Foreground only. Read while you are looking at those screens.
- Never written down. Held in memory to sort a list or draw a dot, and gone when the screen closes.
- Never transmitted. No coordinate is sent to us, to Firebase, or to anyone else. A crowd report carries a station, not a position.
- Refusable, permanently. Decline the permission and every other part of the app works unchanged; you pick your station from the list instead.
This is unchanged from earlier versions of the app and of this policy.
Sharing live train positions — off by default, and it does transmit
Described in full under what the app collects. In short: you switch it on, the app publishes where you are while it believes you are on a train, other riders see a train approaching their station, and you can switch it off at any moment and what you published is deleted.
It is off when you install the app. Nothing is published until you turn it on or start a trip, and either one shows you what it will do before it starts. A trip's sharing ends with the trip.
Withdrawing
You can withdraw location permission at any time in your phone's settings, and the app is built to treat that as a normal answer rather than an error. Withdrawing it stops live positions as well, and any row you published expires within thirty minutes.
05 Push
Notifications
Notifications are opt-in. Nothing is subscribed until you ask for it, and the permission prompt is deliberately not shown on first launch.
If you turn them on, Firebase Cloud Messaging issues your install a
device token and subscribes it to a topic called
advisories. A token is an address for a phone, not a name: we
send to the topic, never to an individual. Advisories are published by hand
and are limited to what is wrong on the network right now.
An advisory may also wake the app for a moment in the background, so the home-screen widget can be brought up to date without you opening the app. That is the only background work the app does: it fetches the current advisories, redraws the widget, and sends nothing.
There is no re-engagement push, no marketing push, and no "your report helped" push. Turning notifications off in the app unsubscribes the topic; turning them off in your phone's settings stops them regardless.
06 On device
What stays on your phone
Some things are stored locally so the app is fast and works offline. None of it is uploaded by us, and all of it goes when you uninstall the app or clear its storage:
- Your own crowd reports, so the app knows you already reported at a station and a tap is never lost when the network is down.
- Downloaded fare and station datasets, plus the manifest describing them.
- Your saved trips, so a commute you price every day is one tap away.
- Your settings — language, units, fare defaults, whether you asked for advisories, and your analytics choice.
- The home-screen widget's contents — the most serious current advisory and your first saved trip, written by the app into a small store the widget can read, and nowhere else.
Clearing the app's data resets all of it. It cannot be recovered by us, because we never had a copy.
One thing we do not control: your phone's own backup. Google and Apple back up app storage to your account by their own rules, so a backup may contain your saved trips and settings. That copy is yours, in your account, and we cannot read it. On Android the app excludes the anonymous ID and the push credential from backup on purpose, so a restored or transferred phone starts with fresh ones.
07 The site
trains.ph itself
This site is static pages. It sets no cookies, runs no analytics, and carries no tracking pixels or embedded social widgets — the social links are ordinary links.
The relaunch form
If you fill in the "notify me at relaunch" form, the email address you type, the line you pick and anything you write in the message box are sent to Kit (formerly ConvertKit), the mailing-list service we use, and are used for one purpose: telling you when the app returns, and reading what you asked for. They are not sold, rented or shared. Every email carries an unsubscribe link, and unsubscribing removes you.
There is a hidden field in that form that a person never sees. If it is filled in, the submission is discarded as spam. It is the only check the form performs, and it looks at the form, not at you.
Hosting and fonts
The site is served by Firebase Hosting, which keeps ordinary server logs, and it loads two typefaces from Google Fonts, which means your browser makes a request to Google to fetch them. Both are in the table below.
08 Processors
Who else handles it
TrainsPh is a small project and runs on other people's infrastructure. This is everyone who touches data on our behalf — the complete list, not a sample. Each is bound by its own terms, and each is outside the Philippines, so your data may be processed abroad.
| Who | What reaches them | Why |
|---|---|---|
| Google Firebase Auth, Realtime Database, Cloud Messaging, App Check, Analytics, Hosting |
Anonymous install ID; crowd reports; live train positions, while you are sharing them; push token and topic; usage analytics events and the app instance ID, unless you switch them off; IP address and request metadata in server logs | Runs the shared crowd data, the advisory pushes, the usage analytics, and both this site and the dataset host |
| Google Play Apple |
Device integrity signals, handled by the platform; whatever the store itself records about your download | Confirms requests come from the real app on a real device; distributes the app |
| Kit formerly ConvertKit |
Email address, chosen line and message — from the website form only, never from the app | Sends the one email announcing the relaunch |
| Google Fonts | Your IP address and browser, when this website loads its two typefaces | Typography on trains.ph. The app bundles its fonts and makes no such request |
We do not sell personal data, and we do not share it with advertisers, data brokers or agencies. Nothing above is a sale, or a disclosure for anyone else's marketing.
09 Limits
What we never do
Stated plainly, because a policy that lists only what a company may do tells you nothing. One item was removed in version 2.0: earlier versions promised location was never transmitted, and live train positions transmit it. That is described above rather than buried here. As of this version, TrainsPh does not:
- ask for your name, email, phone number or any government identifier in the app;
- read your contacts, photos, camera, microphone, calendar, call log or SMS — those permissions are not declared at all;
- read or use an advertising identifier, and shows no ads;
- show other people's websites inside the app — every link goes to your browser or maps app, so nothing you do there passes through TrainsPh;
- run session recording, heatmaps or screen capture of any kind — the usage analytics described above counts events we chose and named, and nothing else;
- attach your location to an analytics event, or record where you have been — live train positions publish where you are now, for thirty minutes, and the database holds no history;
- build a profile of you, or make any automated decision about you;
- sell, rent or trade data to anyone.
If any of this changes, it changes here first — see changes to this policy.
10 Retention
How long it is kept
- Crowd reports stop affecting what anyone sees after 45 minutes — that is the only window the app reads. An older row is never shown to anyone and holds nothing but a station, a level, a time and a random install ID.
- Crowd reports are deleted after 90 days. This is not a policy we promise to remember: the database rules permit no one to delete a report before 90 days, and permit anyone to delete it after, so expiry is a property of the data rather than of a job that could quietly stop running. A report can never be edited or withdrawn while it still counts.
- Live train positions are deleted after 30 minutes, and stop being shown to anyone after 10. As with crowd reports this is enforced in the database rules rather than promised: nothing may read a position that old, and anyone may delete it. Unlike a crowd report, you can delete your own at any time, and switching the feature off does exactly that.
- No position history is kept. Each new position replaces your previous one rather than adding to a list, so no coordinate of yours outlives the next. The ride records below do name stations — a stretch you rode, a line you changed at — and each carries your anonymous ID, which is why they are kept for 90 days and no longer.
- Run times, stops, door answers and transfer times are deleted after 90 days, enforced in the database rules the same way. What is learned from them carries no ID and is kept.
- Train departures are deleted after 90 days, enforced in the database rules the same way as crowd reports. Each says only that a train on a line and direction left its first station at a time, keyed to your anonymous ID. The headways learned from them carry no ID and are kept.
- The anonymous ID lasts as long as the installation. Uninstalling ends it.
- Push tokens last until you unsubscribe, uninstall, or the platform expires the token.
- Server logs are kept by Google on Google's schedule; we do not query them.
- Wrong-fare emails are kept while the fare is being checked and the data corrected, and deleted when you ask.
- Website signups are kept until you unsubscribe or ask us to delete them, and in any case no longer than the relaunch announcement needs them.
11 Rights
Your rights
Under the Data Privacy Act of 2012 you have the right to be informed, and the rights of access, correction, objection, erasure or blocking, damages, data portability, and to complain to the National Privacy Commission.
Email taioappsdevelopment@gmail.com and we will answer within 15 days. Two honest limits on what we can do:
- App data cannot be traced back to you, because we never learn who you are. A crowd report holds a station, a level, a time and a random install ID. Unless you can tell us that ID, we have no way to find "your" rows and no way to verify they are yours — which is a privacy protection, not an evasion. Uninstalling is what ends the association at your end.
- Crowd reports are append-only by design. The database rules permit no edit, and no delete until the report is 90 days old, so an individual report cannot be retracted after it is written. It ages out of every reading within 45 minutes and is deleted entirely at 90 days.
- Live train positions are the exception, and the good kind. Your position row is keyed by your install's anonymous ID, and the app can delete it because it knows its own ID. Switching live positions off erases it immediately — you do not have to ask us, and we could not do it faster than you can.
Website signups and wrong-fare emails are different: there we hold an email address, so access, correction and deletion are straightforward. Ask, or for signups use the unsubscribe link in any email.
12 Children
Children
TrainsPh is a commuting tool for a general audience, not a service directed at children. It collects no personal information from anyone, children included — there is no account, no name and no contact detail to collect. The website form asks for an email address and is intended for adults.
If you believe a child has sent us personal information through the website form, email us and we will delete it.
13 History
The 2017 app
The first TrainsPh shipped in 2017 and is no longer on the store. It is worth saying what happened to its data rather than quietly dropping the subject.
That version identified devices by ANDROID_ID, which the
client supplied and the server could not verify, and it wrote to a database
whose nodes — chat, ratings, active users — could be read by anyone who
found the URL. Its backend is gone, and every one of those nodes is closed
in the current rules rather than carried forward. Nothing from it feeds the
new app.
The 2017 app also showed live station CCTV supplied by the Department of Transportation. That access ended with the old app; no video reaches the new one.
14 Changes
Changes to this policy
The app is being rebuilt, so this policy will change as features land. The version number and effective date at the top of this page move every time it does.
If a change means collecting something new, or using something already collected for a different purpose, we will say so in the app before it takes effect — not only here.
15 Contact
Ask us anything about this
John Nicholai Villegas, TAIO Labs — Philippines
taioappsdevelopment@gmail.com
If you are not satisfied with how we answer, you may bring a complaint to the National Privacy Commission of the Philippines at privacy.gov.ph.