<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Building BingeMark]]></title><description><![CDATA[Building BingeMark]]></description><link>https://bingemark.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Building BingeMark</title><link>https://bingemark.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 25 Sep 2026 08:11:48 GMT</lastBuildDate><atom:link href="https://bingemark.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I built a movie/TV/anime tracker with React Native, FastAPI & MongoDB (and the AdMob bug that nearly broke me)]]></title><description><![CDATA[I just shipped BingeMark, a free Android app that tracks movies, TV shows and anime in one place. Here's the stack and two bugs that ate a weekend each.
The stack

Frontend: React Native + Expo (SDK 5]]></description><link>https://bingemark.hashnode.dev/how-i-built-a-movie-tv-anime-tracker-with-react-native-fastapi-mongodb-and-the-admob-bug-that-nearly-broke-me</link><guid isPermaLink="true">https://bingemark.hashnode.dev/how-i-built-a-movie-tv-anime-tracker-with-react-native-fastapi-mongodb-and-the-admob-bug-that-nearly-broke-me</guid><category><![CDATA[Movies]]></category><category><![CDATA[tv]]></category><category><![CDATA[Anime]]></category><category><![CDATA[tracker]]></category><category><![CDATA[watchlist]]></category><category><![CDATA[app]]></category><category><![CDATA[tracking]]></category><category><![CDATA[Android]]></category><category><![CDATA[Playstore]]></category><dc:creator><![CDATA[Rahul Shinde]]></dc:creator><pubDate>Mon, 21 Sep 2026 14:49:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ab1422421cfeadb065f5d5d/e58783ce-ee53-4a90-a012-65adfe4bef30.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I just shipped <strong>BingeMark</strong>, a free Android app that tracks movies, TV shows and anime in one place. Here's the stack and two bugs that ate a weekend each.</p>
<h4>The stack</h4>
<ul>
<li><p><strong>Frontend:</strong> React Native + Expo (SDK 54)</p>
</li>
<li><p><strong>Backend:</strong> Python + FastAPI</p>
</li>
<li><p><strong>Database:</strong> MongoDB Atlas</p>
</li>
<li><p><strong>Hosting:</strong> Render</p>
</li>
<li><p><strong>Data:</strong> TMDB API (titles, images), OMDb (IMDb ratings)</p>
</li>
<li><p><strong>Extras:</strong> Google Sign-In, Google Drive backup (drive.file scope), AdMob for ads</p>
</li>
</ul>
<h4>One app for movies, TV <em>and</em> anime</h4>
<p>Most trackers pick one lane. I wanted all three. The trick was treating everything as TMDB-shaped data, anime is just TV/movie entries under the hood, so one data model and one UI handle all three instead of three separate flows.</p>
<h4>Bug 1: AdMob broke my release build</h4>
<p>Adding <code>react-native-google-mobile-ads</code> blew up the Gradle build with <code>compileReleaseKotlin FAILED</code>. The cause: the newer ads SDK was compiled with Kotlin 2.3, but Expo SDK 54 uses Kotlin 2.1 - a metadata mismatch. Fix: pin the library to a version that ships an older <code>play-services-ads</code> compiled against Kotlin 2.1. Lesson: with Expo, your native deps have to match the Kotlin version Expo bundles.</p>
<h4>Bug 2: a rewatch that wouldn't save</h4>
<p>Logging a second rewatch threw a 500. It was a classic Python datetime trap, comparing a <strong>naive</strong> datetime (from Mongo) with an <strong>aware</strong> one (freshly created) inside a <code>max()</code>. Fix: a small helper that normalizes everything to UTC-aware before comparing.</p>
<h4>Takeaways</h4>
<ul>
<li><p>Match native dependency versions to your Expo/Kotlin version <em>before</em> you debug for hours.</p>
</li>
<li><p>Always store and compare datetimes as timezone-aware.</p>
</li>
<li><p>Keep one clean data model even when the content types look different. It saves you everywhere later.</p>
</li>
</ul>
<p>It's live if you want to poke at it: <a href="https://play.google.com/store/apps/details?id=com.bingemark.app">Link</a><br />Happy to answer anything about the stack in the comments.</p>
]]></content:encoded></item></channel></rss>