Nom Nom Calories
Nom Nom Calories ("the App") is a calorie, macro and activity tracking app for Android. The App requires an account and stores your data on our servers so it survives a reinstall and stays consistent across sessions. This policy describes exactly what we collect, where it is kept, who else sees it, and what you can do about it.
We do not show ads, the App contains no advertising SDK, and we do not sell or rent your data.
You sign in with your phone number. The App sends the number to Google Firebase Authentication, which delivers a one-time SMS code; confirming that code signs you in and gives the App an identity token. We never see or store your SMS code.
On first sign-in we create an account record on our servers, keyed to the Firebase user id. That record can hold:
Your tracking data lives in your account. This is what we keep:
All traffic between the App and our servers runs over HTTPS.
Some data is kept on the phone, either as a local mirror or because it should never leave:
Android's cloud backup is enabled for the App, but its backup rules include only the App's small preference files, and explicitly exclude the encrypted secure store. So your AI key is never in a device backup, and neither is the local copy of your diary or any photo the App saved.
The camera and photo library are used only when you start one of these actions: analysing a meal from a photo, attaching a photo to a logged meal, submitting a group proof photo, setting a group cover image, or setting your profile photo.
On Android you can connect the App to Health Connect, the system health store on your phone. Nothing is read until you grant permission in the system sheet.
The App asks to read these record types: Steps, Exercise sessions, Sleep sessions, Distance, Active calories burned, and Total calories burned. It also asks for the Health Connect "read history" permission, which allows reading records older than 30 days. Background reading is a separate, optional request made from the Connections screen. The sync itself runs while the App is open, so declining that request does not stop your data syncing. The release build of the App declares no Health Connect write permission: it never writes anything back into your health store.
What we upload to your account is summarised, not raw:
When you first connect, the App backfills the last 30 days. After that it syncs yesterday and today when you bring the App to the foreground, and not more often than once every 15 minutes. Each metric has its own toggle, and a metric you turn off is not read or sent.
Tapping Disconnect in the App stops the sync. Data already synced to your account stays until you delete the account (section 12). Revoking the App's access inside Health Connect settings stops it at the source.
Social features are opt-in in the sense that nothing happens until you add a friend or create a group.
When you describe a meal in words, or submit a photo of a meal, that content is sent to our own AI service, which forwards it to an external model provider to get a food and macro estimate back. Two smaller features run through the same service: a recipe for a meal you name, and a suggested recipe built around the macros you have left on a day.
glm-5.2 and photo estimates use qwen3.6-35b-fast. If you have supplied your own AI key, the text features go to your own provider instead; see "Using your own AI key" below.You can supply your own provider key instead of using our allowance. The App accepts one provider's key today, Groq, and it is stored in your device's encrypted secure store. It covers the text features: text estimates, recipes and suggested recipes. When you make one of those, the key is attached to that single request, and our AI service uses it as the authorisation for one model call to Groq, the provider that key belongs to, not to the AI vendor our own calls run on. It authorises that one call and nothing else. We do not store the key, and it is not written to our logs. On your account we record only a true/false flag saying that you are using your own key.
A call that runs on your key does not touch your daily allowance and is not counted, because it costs us nothing.
Photo estimates work differently. They always run on our own key, never on yours, and they always count against your daily allowance even when you have supplied a personal key. The App does not attach your key to a photo estimate at all.
Estimates of workouts and weight are not AI features. Your daily calorie target is calculated with the Mifflin St Jeor formula, not a model.
The App and our servers send product events to PostHog. Session replay, autocapture, automatic lifecycle events and surveys are all disabled.
The App uses Sentry to capture crashes and errors, including native Android crashes and ANRs. Sentry receives error messages, stack traces, device and OS metadata, screen navigation breadcrumbs, and breadcrumbs for failed API calls (method, service, path, status code, duration and request id). You are identified to Sentry only by the anonymous device UUID, not by your phone number or account id. Session replay is off, and 20 percent of performance traces are sampled.
Separately from those, the Sentry SDK keeps a network breadcrumb for each recent API request the App made, and a network breadcrumb carries that request's URL. Before a breadcrumb leaves the device the App strips Authorization headers, the headers that carry your own AI key, anything matching a provider key pattern, and any phone number sitting in the URL's parameters. Only network breadcrumbs carry request URLs; navigation and console breadcrumbs do not.
The same stripping is applied to request data, error messages and stack frame variables before an event is sent.
The App uses ConfigCat to turn features on and off remotely. It receives only the anonymous device UUID, so a given device gets a stable answer. No account or personal data is sent.
Our services do not write an access log. There is no per-request record of the raw request line, so a query string, which is where a phone number would sit during a friend search, never reaches a log file at all.
What we do write are our own application log lines: what an operation did, how it ended, and internal identifiers such as the request id and the account id it belongs to. They do not carry diary content, phone numbers or keys. When one of our services logs the address of a call it made to another service, that address is scrubbed first. Logs are for diagnosing failures, not for analysing your diary.
Subscriptions are sold through Google Play and managed by RevenueCat. The App never sees, handles or stores your card details; the purchase happens in the Google Play sheet.
RevenueCat is configured with your Firebase user id as the customer id, so a purchase attaches to your account. RevenueCat notifies our server over an authenticated webhook, and we store the resulting subscription state: active or not, expiry, product id, and the RevenueCat customer id, plus a copy of the notification RevenueCat sent us, kept so the same notification cannot be replayed against your account. We clear the contents of that copy after 180 days and keep only the record that the notification arrived, which is the part that stops a replay. Restoring purchases asks Google Play and RevenueCat for your existing entitlements.
Deleting your account does not cancel a Google Play subscription. That billing belongs to Google Play, not to us, so a subscription left running keeps renewing after the account is gone. Cancel it in Google Play first. See how to delete your account.
The table below lists the permissions that matter for privacy, and why they are there. Some are declared by the libraries the App is built on rather than requested by a feature; those are marked as such. The last row covers the remainder.
| Permission | Why it is there |
|---|---|
| INTERNET | Talking to our servers and the third parties listed in section 13. |
| ACCESS_NETWORK_STATE | Declared by the Sentry SDK. |
| CAMERA | Taking meal photos, group proof photos, group cover images and your profile photo. |
| READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE | Picking an existing image from your library, on Android 12L and older only (declared with maxSdkVersion 32). |
| RECORD_AUDIO | Declared by the camera and image picker modules so that video capture can include sound. The App has no voice or audio recording feature. |
| VIBRATE | Haptic feedback on taps and confirmations. |
| WAKE_LOCK | Declared by the Firebase Authentication SDK. |
| POST_NOTIFICATIONS | Water reminders and fasting milestone alerts. These are scheduled and fired locally, on your device. |
| RECEIVE_BOOT_COMPLETED | Rescheduling those local reminders after a restart. |
| health.READ_STEPS, READ_EXERCISE, READ_SLEEP, READ_DISTANCE, READ_ACTIVE_CALORIES_BURNED, READ_TOTAL_CALORIES_BURNED | Reading the health data described in section 6, only after you grant it. |
| health.READ_HEALTH_DATA_HISTORY | Reading health records older than 30 days, for the initial backfill. |
| health.READ_HEALTH_DATA_IN_BACKGROUND | Optional. Requested separately from the Connections screen. |
| Everything else, declared by libraries | The Play billing, Firebase and notification libraries bring further permissions of their own: Play billing, lookups against Google Play services, home-screen badge counts, and the permission to receive a Firebase Cloud Messaging message. We do not register for push notifications, so nothing is ever delivered on that last one. None of these is requested from you at runtime, and none is used to collect data. |
The App also declares that it can see two other apps on your device: Health Connect, so it can tell whether the provider is installed, and Instagram, so the "share to Stories" button can work. It cannot read anything from either.
The App requests no location permission, no contacts permission and no advertising identifier.
Internal copies outlive the content. Deleting something takes it out of the App and out of every total, streak and feed we calculate, but it does not erase every internal copy at the same moment. A post or comment leaves every view immediately and the row behind it is erased 30 days later, by a background sweep on the service that holds it. An idempotency replay copy still holds the response we already sent for that write; it stops being replayable after 24 hours and its row is deleted at 48, by the same kind of sweep on each service that keeps one. A deleted diary row is the one with no horizon: it stays flagged as deleted for as long as the account does, because it is what tells your other devices the entry is gone. The security audit trail is append-only by design and is not swept. Deleting the account, below, is what clears the rest.
Logging out signs you out of Firebase and clears the account-scoped data on the device: the local diary, targets, sync bookkeeping, the local AI usage counter, the local display name and the local profile photo copy. Device-level values survive a logout: the theme, the anonymous device UUID, your AI provider and model choice, and your own AI key in the secure store. Uninstalling the App removes all of its on-device storage, including the secure store and the photos it saved. Neither action deletes your data from our servers.
Settings has a Delete account option. It asks you to confirm twice, because this cannot be undone. On the second confirmation the App calls our servers, and the account is locked and signed out immediately, on every device: from that moment nothing can be logged, read or shared with it, and a device still holding a valid sign-in is refused rather than served. The App then clears its own storage on the device back to a fresh-install state. Unlike a log out, that includes the device-level values in section 4: the theme, the anonymous device UUID, your AI provider choice and your own AI key in the secure store all go too.
The erasure of your data across our services runs in the background rather than while you wait. The work starts straight away, a background sweep keeps at it every 15 minutes, and any part that fails is retried, so it typically finishes within a few hours. It is deliberately never marked finished sooner than 2 hours after you ask: a device that has not noticed yet can hold a valid sign-in for up to an hour, so the sweep waits that window out and clears anything that arrived after its first pass. It erases the server data described in sections 2, 3, 5, 6 and 7.
Three things are deliberately kept. The first is your account row, scrubbed: the phone number, the hash of it, the display name, the @handle, the monogram initial and the goal labels are all emptied in the same statement that marks it deleted. What is left is a tombstone carrying the internal id, the sign-in id it was keyed to, settings that describe nobody (units, profile visibility, sharing level, monogram colour) and timestamps, the notification bookkeeping in section 2 included. It stays because it is what keeps that sign-in locked out, and clearing the phone number and its hash is also what lets the same number sign up again later, as a new account. The other two are records of what happened rather than copies of your content: the security audit trail entries for that account, and the payment notification records RevenueCat sent us. We keep those for security and billing integrity.
Deleting your account does not cancel a Google Play subscription; see section 10.
If you cannot sign in, email contact@nomnomcalories.com, tell us the phone number the account is registered to, and we will delete it for you. The same address is where to ask for a copy of your data. There is also a standalone page describing the process: how to delete your account.
| Service | What it receives |
|---|---|
| Google Firebase Authentication | Your phone number, in order to send and verify the SMS code, and it issues the user id your account is keyed to. |
| Microsoft Azure | Hosts our services, stores uploaded media, and holds short-lived AI job data in a managed cache. |
| Neon | Hosts the PostgreSQL databases behind our social and wellness services, over TLS. |
| MongoDB Atlas | Hosts the databases behind our food catalogue and user configuration services. |
| Neuralwatt | The meal text or meal photo you submit for AI analysis, and the model name. This is the vendor our own AI allowance runs on, and it is the only one a photo estimate ever reaches. |
| Groq | Only if you have supplied your own AI key: the meal text you submit, the model name, and that key, used as the authorisation for that one call. See section 8. |
| PostHog | Product analytics events, identified by the anonymous device UUID before sign-in and by your Firebase user id afterwards. No content, no phone number. |
| Sentry | Crash and error reports, stack traces, device and OS metadata, and breadcrumbs: navigation, failed requests, and the URLs of recent API requests with credentials and phone numbers stripped. Identified by the anonymous device UUID. |
| ConfigCat | The anonymous device UUID, to evaluate feature flags. |
| RevenueCat | Subscription purchase and status information, keyed to your Firebase user id. |
| Google Play | Processes the payment for a subscription. |
Each service handles the data it receives under its own privacy policy: Firebase, Microsoft Azure, Groq, Neon, MongoDB, PostHog, Sentry, ConfigCat, RevenueCat, Google.
The App is not directed at children under 13, and the lowest age its onboarding accepts is 14. We do not knowingly collect data from children under 13. If you believe a child under 13 has an account, contact us and we will delete it.
We update this policy when the App changes what it collects or who it sends data to. The current version always lives at nomnomcalories.com, with the date below. The App also shows a shorter summary of this policy in Settings.
Questions and data requests: contact@nomnomcalories.com. To delete your account, use Delete account in the App's Settings, or see how to delete your account; write to the same address if you cannot sign in. The App's Feedback option opens a pre-filled email to that address; it does not send anything to us by itself, and the message text is never included in analytics.
Last updated: July 31, 2026