[{"data":1,"prerenderedAt":2982},["ShallowReactive",2],{"\u002Fblog\u002Fplay-billing-library-7-deprecated-update-to-8-2026\u002F":3,"\u002Fblog\u002Fplay-billing-library-7-deprecated-update-to-8-2026\u002F-related":538,"\u002Fblog\u002Fplay-billing-library-7-deprecated-update-to-8-2026\u002F-resources":2966},{"id":4,"title":5,"author":6,"body":10,"category":470,"createdAt":471,"description":472,"disclosure":473,"extension":474,"faq":475,"howTo":473,"lastVerified":473,"location":494,"meta":495,"navigation":501,"ogImage":473,"path":502,"primaryKeyword":503,"readingTime":504,"related":505,"seo":509,"sources":510,"stem":528,"tags":529,"takeaways":530,"updatedAt":471,"url":536,"__hash__":537},"blog\u002Fblog\u002Fplay-billing-library-7-deprecated-update-to-8-2026.md","Play Billing Library 7 Deprecated: Update to 8 by November 1",{"name":7,"social":8},"Simon Dziak",{"twitter":9},"@SzymonDziak",{"type":11,"value":12,"toc":461},"minimark",[13,26,29,35,40,43,127,138,141,167,171,174,255,270,274,349,352,374,378,381,445,449],[14,15,16,20,21,25],"p",{},[17,18,19],"strong",{},"If Play Console warns that your app uses an unsupported version of the Google Play Billing Library, version 7 is the likely cause: its deadline for new apps and updates was August 31, 2026, and Google says the extension it offers runs until November 1, 2026."," Google says existing apps keep working, and new apps and updates must use a supported version. In my reading, an app still on version 7 can't ship an update once the extension runs out. For a Flutter app, that usually means a newer ",[22,23,24],"code",{},"in_app_purchase"," or RevenueCat package, and possibly a newer Flutter.",[14,27,28],{},"The deadlines below come from Google's Billing Library deprecation page and release notes, and the package versions from pub.dev and RevenueCat's changelog, as listed in the sources. I checked each one on October 18, 2026.",[14,30,31,34],{},[17,32,33],{},"Disclosure:"," App369 is my studio. I build and fix apps, including in-app purchases and subscriptions in Flutter, and the last section mentions what I sell. Google and RevenueCat don't pay me for anything on this page.",[36,37,39],"h2",{"id":38},"the-deadlines","The deadlines",[14,41,42],{},"Google gives every Billing Library version a two-year deprecation cycle. Its table:",[44,45,46,62],"table",{},[47,48,49],"thead",{},[50,51,52,56,59],"tr",{},[53,54,55],"th",{},"Version",[53,57,58],{},"New apps and updates must move by",[53,60,61],{},"Extension deadline",[63,64,65,77,88,105,116],"tbody",{},[50,66,67,71,74],{},[68,69,70],"td",{},"5",[68,72,73],{},"August 31, 2024",[68,75,76],{},"November 1, 2024",[50,78,79,82,85],{},[68,80,81],{},"6",[68,83,84],{},"August 31, 2025",[68,86,87],{},"November 1, 2025",[50,89,90,95,100],{},[68,91,92],{},[17,93,94],{},"7",[68,96,97],{},[17,98,99],{},"August 31, 2026",[68,101,102],{},[17,103,104],{},"November 1, 2026",[50,106,107,110,113],{},[68,108,109],{},"8",[68,111,112],{},"August 31, 2027",[68,114,115],{},"November 1, 2027",[50,117,118,121,124],{},[68,119,120],{},"9",[68,122,123],{},"August 31, 2028",[68,125,126],{},"November 1, 2028",[14,128,129,130,137],{},"Source: ",[131,132,136],"a",{"href":133,"rel":134},"https:\u002F\u002Fdeveloper.android.com\u002Fgoogle\u002Fplay\u002Fbilling\u002Fdeprecation-faq",[135],"nofollow","Google Play Billing Library version deprecation",", last updated September 9, 2026.",[14,139,140],{},"Google's FAQ also says:",[142,143,144,151,161],"ul",{},[145,146,147,150],"li",{},[17,148,149],{},"Existing apps still work."," Unmaintained APKs don't need updates. The rule applies to new apps and updates.",[145,152,153,156,157,160],{},[17,154,155],{},"The dependency check applies to APKs that use billing."," Google says these dependencies only appear in APKs that require the ",[22,158,159],{},"com.android.vending.BILLING"," permission.",[145,162,163,166],{},[17,164,165],{},"The extension form is in Play Console."," An app on an unsupported version gets a warning. Open its details on the Policy status page to find the form.",[36,168,170],{"id":169},"what-changed-in-version-8","What changed in version 8",[14,172,173],{},"Version 8.0.0 was released on June 30, 2025. Per Google's release notes, the changes most likely to break an older integration are:",[44,175,176,186],{},[47,177,178],{},[50,179,180,183],{},[53,181,182],{},"Change in 8.0.0",[53,184,185],{},"What to use instead",[63,187,188,203,215,232,244],{},[50,189,190,196],{},[68,191,192,195],{},[22,193,194],{},"queryPurchaseHistory()"," removed",[68,197,198,199,202],{},"Google lists ",[22,200,201],{},"queryPurchasesAsync()"," for acknowledged and pending purchases, says to track consumed purchases on your own servers, and points to the voided-purchases API for canceled ones",[50,204,205,210],{},[68,206,207,195],{},[22,208,209],{},"querySkuDetailsAsync()",[68,211,212],{},[22,213,214],{},"queryProductDetailsAsync()",[50,216,217,223],{},[68,218,219,222],{},[22,220,221],{},"enablePendingPurchases()"," with no arguments removed",[68,224,225,228,229],{},[22,226,227],{},"enablePendingPurchases(PendingPurchasesParams)",". The old call equals ",[22,230,231],{},"PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()",[50,233,234,239],{},[68,235,236,195],{},[22,237,238],{},"queryPurchasesAsync(String skuType, ...)",[68,240,241],{},[22,242,243],{},"queryPurchasesAsync(QueryPurchasesParams, ...)",[50,245,246,252],{},[68,247,248,251],{},[22,249,250],{},"onProductDetailsResponse()"," signature changed",[68,253,254],{},"Handle the new result, which also lists products that couldn't be fetched",[14,256,257,258,261,262,265,266,269],{},"Version 8 also added optional automatic service reconnection (",[22,259,260],{},"enableAutoServiceReconnection()",") and sub-response codes on ",[22,263,264],{},"launchBillingFlow()",", such as ",[22,267,268],{},"PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS",". In-app items are now called one-time products.",[36,271,273],{"id":272},"flutter-apps-which-package-versions-include-version-8","Flutter apps: which package versions include version 8",[44,275,276,289],{},[47,277,278],{},[50,279,280,283,286],{},[53,281,282],{},"Package",[53,284,285],{},"First version on Billing Library 8",[53,287,288],{},"Notes, per its changelog or pubspec",[63,290,291,314,332],{},[50,292,293,298,304],{},[68,294,295],{},[22,296,297],{},"in_app_purchase_android",[68,299,300,303],{},[17,301,302],{},"0.5.0"," (May 27, 2026)",[68,305,306,307,310,311],{},"Updates from 7.1.1 to 8.0.0. Breaking: removes ",[22,308,309],{},"queryPurchaseHistory",", use ",[22,312,313],{},"queryPurchases",[50,315,316,320,326],{},[68,317,318],{},[22,319,24],{},[68,321,322,325],{},[17,323,324],{},"3.3.0"," (June 3, 2026)",[68,327,328,329,331],{},"Depends on ",[22,330,297],{}," ^0.5.0. Requires Flutter 3.38 or later and Dart 3.10",[50,333,334,340,346],{},[68,335,336,339],{},[22,337,338],{},"purchases_flutter"," (RevenueCat)",[68,341,342,345],{},[17,343,344],{},"9.0.0"," (July 18, 2025)",[68,347,348],{},"Billing Library 8. Version 10.0.0 moved to 8.3.0 and raised the Android minimum to API 23",[14,350,351],{},"Two things to watch:",[142,353,354,368],{},[145,355,356,361,362,364,365,367],{},[17,357,358,360],{},[22,359,24],{}," needs a recent Flutter."," Version 3.2.3, the last one on the old Android package, depended on ",[22,363,297],{}," ^0.4.0, which used Billing Library 7.1.1. To get version 8 through Flutter's own plugin, the app has to run on Flutter 3.38 or later. Flutter's release archive dates 3.38.0 November 12, 2025. Every ",[22,366,297],{}," release after 0.5.0 requires Flutter 3.44 or later, so on Flutter 3.38 to 3.43 pub can only use 0.5.0. My advice: if the app is on an older Flutter, plan the Flutter upgrade and the billing update as one job, because the upgrade can surface other build errors.",[145,369,370,373],{},[17,371,372],{},"RevenueCat warns about consumables."," Its 9.0.0 notes say Billing Library 8 can no longer query expired subscriptions or consumed one-time products. If a lifetime purchase is set up as a consumable in the RevenueCat dashboard, RevenueCat will consume it, and users can't restore it. RevenueCat says to set those products up as non-consumables.",[36,375,377],{"id":376},"what-to-do-now","What to do now",[14,379,380],{},"This section is my advice, not Google's.",[382,383,384,407,413,425,431],"ol",{},[145,385,386,389,390,393,394,397,398,400,401,393,403,406],{},[17,387,388],{},"Find the version you ship."," In a native app, check ",[22,391,392],{},"com.android.billingclient:billing"," in ",[22,395,396],{},"build.gradle",". In Flutter, check ",[22,399,297],{}," or ",[22,402,338],{},[22,404,405],{},"pubspec.lock",", and compare with the table above.",[145,408,409,412],{},[17,410,411],{},"Request the extension if you need time."," If you can't ship version 8 before your next update, use the form from the Play Console warning. Google's extension for version 7 ends on November 1, 2026, so as of October 18, 2026 it buys two weeks at most.",[145,414,415,418,419,421,422,424],{},[17,416,417],{},"Upgrade the package, then fix what broke."," Look for the removed calls in the version 8 table. In Flutter, replace ",[22,420,309],{}," with ",[22,423,313],{},".",[145,426,427,430],{},[17,428,429],{},"Test purchases and restores before you ship."," Use Play Console license testers to buy, cancel and restore each product type, especially one-time products and anything users expect to restore after reinstalling.",[145,432,433,436,437,440,441,444],{},[17,434,435],{},"Check the manifest if the warning stays."," Google says the merged ",[22,438,439],{},"AndroidManifest.xml"," must contain ",[22,442,443],{},"com.google.android.play.billingclient.version",". If it doesn't, check whether manifest merging removes it.",[36,446,448],{"id":447},"need-a-hand","Need a hand?",[14,450,451,452,456,457,424],{},"If an app can't ship an update because of the Billing Library deadline, or purchases broke after the upgrade, the ",[131,453,455],{"href":454},"\u002Ffixed-price\u002Fflutter-firebase-bug-fix\u002F","App Fix Ticket"," covers it in two fixed-price steps. A $450 Diagnosis gives you the root cause with evidence and a fixed repair quote within 3 business days, credited toward the fix. If you go ahead, the $1,200 Fix takes 5 business days and comes as a pull request. Or ",[131,458,460],{"href":459},"\u002Fcontact\u002F","send me a short description",{"title":462,"searchDepth":463,"depth":463,"links":464},"",2,[465,466,467,468,469],{"id":38,"depth":463,"text":39},{"id":169,"depth":463,"text":170},{"id":272,"depth":463,"text":273},{"id":376,"depth":463,"text":377},{"id":447,"depth":463,"text":448},"AI & Technology","2026-10-18T23:30:00.000Z","Google Play Billing Library 7 hit its deadline on August 31, 2026: new apps and updates must use version 8 or later, and Google says its extension runs until November 1, 2026. What changed in version 8, which Flutter in_app_purchase and RevenueCat versions include it, and how to clear the Play Console warning, from Google's docs checked October 18, 2026.",null,"md",[476,479,482,485,488,491],{"question":477,"answer":478},"When is Play Billing Library 7 deprecated?","Google's deprecation table sets August 31, 2026 as the deadline for new apps and updates on version 7, and November 1, 2026 as the extension deadline. Google's banner on the same page says that by August 31, 2026, new apps and updates must use version 8 or later.",{"question":480,"answer":481},"What happens if I don't update the Billing Library?","Google says existing apps still work and unmaintained APKs don't need updates, but new apps and updates must use a supported version. My reading: once your deadline passes, you can't publish an update to an app that uses version 7 or older.",{"question":483,"answer":484},"How do I get an extension to November 1, 2026?","Google says an app on an unsupported version gets a warning in Play Console. Open the warning's details on the Policy status page and use the extension form there. Google says the extension for version 7 runs until November 1, 2026.",{"question":486,"answer":487},"Which Flutter in_app_purchase version uses Billing Library 8?","in_app_purchase_android 0.5.0, published May 27, 2026, updated the Billing Library from 7.1.1 to 8.0.0. The in_app_purchase package depends on it from version 3.3.0, which requires Flutter 3.38 or later and Dart 3.10.",{"question":489,"answer":490},"I already updated. Why does Play Console still show the warning?","Google's FAQ says to check that your AndroidManifest.xml contains com.google.android.play.billingclient.version, and if it is missing, whether manifest merging removes it.",{"question":492,"answer":493},"Do I need to move to version 9?","Not for this deadline. Version 8 is supported until August 31, 2027, with an extension to November 1, 2027, per Google's table. Version 9 was released on May 19, 2026 and is supported a year longer.","Boynton Beach, FL",{"readingTimeStats":496},{"text":497,"minutes":498,"time":499,"words":500},"5 min read",4.115,246900,823,true,"\u002Fblog\u002Fplay-billing-library-7-deprecated-update-to-8-2026","play billing library 7 deprecated","7 min",[506,507,508],"revenuecat-stripe-firebase-monetization-stack-template369","flutter-gradle-plugin-applied-imperatively-fix-2026","flutter-deleted-android-v1-embedding-build-failed-2026",{"title":5,"description":472},[511,513,516,519,522,525],{"title":512,"url":133},"Android Developers, Google Play Billing Library version deprecation (last updated September 9, 2026)",{"title":514,"url":515},"Android Developers, Google Play Billing Library release notes","https:\u002F\u002Fdeveloper.android.com\u002Fgoogle\u002Fplay\u002Fbilling\u002Frelease-notes",{"title":517,"url":518},"pub.dev, in_app_purchase_android changelog","https:\u002F\u002Fpub.dev\u002Fpackages\u002Fin_app_purchase_android\u002Fchangelog",{"title":520,"url":521},"pub.dev, in_app_purchase versions","https:\u002F\u002Fpub.dev\u002Fpackages\u002Fin_app_purchase\u002Fversions",{"title":523,"url":524},"RevenueCat purchases-flutter changelog on GitHub","https:\u002F\u002Fgithub.com\u002FRevenueCat\u002Fpurchases-flutter\u002Fblob\u002Fmain\u002FCHANGELOG.md",{"title":526,"url":527},"Flutter release archive (macOS)","https:\u002F\u002Fstorage.googleapis.com\u002Fflutter_infra_release\u002Freleases\u002Freleases_macos.json","blog\u002Fplay-billing-library-7-deprecated-update-to-8-2026","play billing library 7 deprecated, play billing library 8 migration, unsupported version of google play billing library, play console billing library warning, billing library extension november 1 2026, in_app_purchase_android billing 8, purchases_flutter billing library 8, querypurchasehistory removed, flutter in app purchase android update",[531,532,533,534,535],"Every Google Play Billing Library version has a two-year deprecation cycle. For version 7, Google says the deadline for new apps and updates was August 31, 2026, and the extension deadline is November 1, 2026.","Version 8.0.0 (June 30, 2025) removed queryPurchaseHistory(), querySkuDetailsAsync(), the no-argument enablePendingPurchases() and the queryPurchasesAsync() overload that takes a SKU type, and changed the queryProductDetailsAsync() result.","Flutter's in_app_purchase_android moved to Billing Library 8.0.0 in version 0.5.0 (May 27, 2026). The app-facing in_app_purchase package uses it from 3.3.0, which needs Flutter 3.38 or later.","RevenueCat's purchases_flutter moved to Billing Library 8 in 9.0.0 (July 18, 2025). Its notes warn that one-time products wrongly set up as consumables can no longer be restored.","Google says existing apps keep working. The deadline applies to new apps and updates. My reading: an app on version 7 can't ship an update until it moves, once any extension runs out.","https:\u002F\u002Fapp369.com\u002Fblog\u002Fplay-billing-library-7-deprecated-update-to-8-2026\u002F","5n6ohencoIcRhkIOzQZqt84R1BDU1_moCs_avK-ktvg",[539,1632,2328],{"id":540,"title":541,"author":542,"body":544,"category":1615,"createdAt":1616,"description":1617,"disclosure":473,"extension":474,"faq":473,"howTo":473,"lastVerified":473,"location":494,"meta":1618,"navigation":501,"ogImage":473,"path":1624,"primaryKeyword":473,"readingTime":1625,"related":473,"seo":1626,"sources":473,"stem":1627,"tags":1628,"takeaways":473,"updatedAt":1629,"url":1630,"__hash__":1631},"blog\u002Fblog\u002Frevenuecat-stripe-firebase-monetization-stack-template369.md","RevenueCat + Stripe + Firebase Stack",{"name":7,"social":543},{"twitter":9},{"type":11,"value":545,"toc":1577},[546,549,552,555,584,587,594,599,608,612,615,620,623,645,651,655,658,672,675,679,682,702,705,709,712,726,729,733,736,750,753,759,763,770,774,782,820,825,828,832,839,879,884,887,891,898,930,934,937,941,948,974,977,982,986,992,1018,1022,1025,1029,1032,1036,1080,1084,1121,1125,1152,1156,1181,1187,1191,1195,1215,1219,1242,1247,1251,1254,1286,1289,1293,1305,1343,1346,1350,1354,1371,1375,1392,1396,1413,1417,1420,1451,1454,1458,1461,1464,1470,1487,1492,1499,1507,1516,1519,1523,1529,1535,1541,1547,1553,1559,1565],[14,547,548],{},"You've built an amazing app. Users love it. Now you need to make money from it, subscriptions, in-app purchases, premium features. Simple, right?",[14,550,551],{},"Not quite.",[14,553,554],{},"If you've ever tried to integrate payments across iOS, Android, and web, you know the pain:",[142,556,557,563,569,575,581],{},[145,558,559,562],{},[17,560,561],{},"iOS"," requires App Store In-App Purchases with StoreKit",[145,564,565,568],{},[17,566,567],{},"Android"," needs Google Play Billing",[145,570,571,574],{},[17,572,573],{},"Web"," wants Stripe or another payment processor",[145,576,577,580],{},[17,578,579],{},"macOS"," has its own App Store requirements",[145,582,583],{},"Each platform has different APIs, different validation flows, different receipt systems",[14,585,586],{},"Then there's the backend: webhooks, subscription management, grace periods, refunds, trials, notifications when payments succeed or fail… the list goes on.",[14,588,589,590,593],{},"Most developers spend ",[17,591,592],{},"4-6 weeks"," just getting payments working, and that's if nothing goes wrong. For a startup or indie developer, that's time you don't have and complexity you shouldn't have to wrestle with.",[14,595,596],{},[17,597,598],{},"What if all of this was already done for you?",[14,600,601,602,607],{},"That's exactly what ",[131,603,606],{"href":604,"rel":605},"https:\u002F\u002Ftemplate369.com",[135],"Template369"," delivers: a complete, production-ready monetization stack with RevenueCat, Stripe, and Firebase, pre-integrated, tested, and documented.",[36,609,611],{"id":610},"the-payment-integration-problem-why-its-so-hard","The Payment Integration Problem: Why It's So Hard",[14,613,614],{},"Let's break down why payments across platforms are such a nightmare:",[616,617,619],"h3",{"id":618},"_1-platform-specific-apis","1. Platform-Specific APIs",[14,621,622],{},"Each platform speaks a different language:",[142,624,625,630,635,640],{},[145,626,627,629],{},[17,628,561],{},": StoreKit 2 (or StoreKit 1 for older versions)",[145,631,632,634],{},[17,633,567],{},": Google Play Billing Library 5.0+",[145,636,637,639],{},[17,638,579],{},": App Store with different receipt validation",[145,641,642,644],{},[17,643,573],{},": Stripe Checkout, Payment Intents, webhooks",[14,646,647,648,424],{},"You're not building one payment system, you're building ",[17,649,650],{},"four",[616,652,654],{"id":653},"_2-backend-validation-security","2. Backend Validation & Security",[14,656,657],{},"Processing payments on the client is dangerous. You need:",[142,659,660,663,666,669],{},[145,661,662],{},"Server-side receipt validation (Apple\u002FGoogle could reject your app otherwise)",[145,664,665],{},"Webhook handlers to catch payment events",[145,667,668],{},"Fraud detection and security measures",[145,670,671],{},"Database updates tied to payment status",[14,673,674],{},"This means building a backend, typically with Firebase Cloud Functions, AWS Lambda, or your own server.",[616,676,678],{"id":677},"_3-subscription-lifecycle-management","3. Subscription Lifecycle Management",[14,680,681],{},"Subscriptions aren't \"pay once and done.\" You have to handle:",[142,683,684,687,690,693,696,699],{},[145,685,686],{},"Free trials starting and ending",[145,688,689],{},"Grace periods when payments fail",[145,691,692],{},"Subscription renewals and cancellations",[145,694,695],{},"Refunds and chargebacks",[145,697,698],{},"Subscription upgrades and downgrades",[145,700,701],{},"Family sharing (on Apple platforms)",[14,703,704],{},"Each scenario requires custom logic. Miss one edge case, and users get locked out, or worse, get free access when they shouldn't.",[616,706,708],{"id":707},"_4-cross-platform-syncing","4. Cross-Platform Syncing",[14,710,711],{},"What happens when a user subscribes on iOS, then logs in on web? You need:",[142,713,714,717,720,723],{},[145,715,716],{},"Shared user state across platforms",[145,718,719],{},"Real-time sync of subscription status",[145,721,722],{},"Server-side source of truth (Firestore, PostgreSQL, etc.)",[145,724,725],{},"Proper entitlement checks in your app",[14,727,728],{},"Without this, users pay on one platform but can't access features on another.",[616,730,732],{"id":731},"_5-notifications-user-communication","5. Notifications & User Communication",[14,734,735],{},"When payments succeed, fail, or subscriptions expire, users need to know:",[142,737,738,741,744,747],{},[145,739,740],{},"Push notifications (Firebase Cloud Messaging)",[145,742,743],{},"Email alerts (SendGrid, Mailgun, etc.)",[145,745,746],{},"In-app messaging",[145,748,749],{},"Backend triggers tied to payment events",[14,751,752],{},"Coordinating this with webhooks and Cloud Functions is another layer of complexity.",[14,754,755,758],{},[17,756,757],{},"Total time to build all this from scratch? 4-6 weeks minimum."," And that assumes you already know what you're doing.",[36,760,762],{"id":761},"the-template369-solution-pre-built-production-ready-monetization","The Template369 Solution: Pre-Built, Production-Ready Monetization",[14,764,765,766,769],{},"Template369 eliminates all of this headache by giving you a ",[17,767,768],{},"complete monetization stack"," out of the box:",[616,771,773],{"id":772},"revenuecat-for-mobile-macos","✅ RevenueCat for Mobile & macOS",[14,775,776,781],{},[131,777,780],{"href":778,"rel":779},"https:\u002F\u002Fwww.revenuecat.com",[135],"RevenueCat"," is the industry-standard SDK for managing in-app purchases across iOS, Android, and macOS. Template369 comes with RevenueCat fully integrated:",[142,783,784,790,796,802,808,814],{},[145,785,786,789],{},[17,787,788],{},"iOS In-App Purchases",": StoreKit integration, receipt validation, subscription management",[145,791,792,795],{},[17,793,794],{},"Android Google Play Billing",": Billing Library 5.0+, purchase verification",[145,797,798,801],{},[17,799,800],{},"macOS App Store",": Full support for macOS subscriptions and purchases",[145,803,804,807],{},[17,805,806],{},"Cross-Platform Sync",": RevenueCat handles syncing purchase state across devices",[145,809,810,813],{},[17,811,812],{},"Subscription Analytics",": Built-in dashboards for revenue, churn, and retention",[145,815,816,819],{},[17,817,818],{},"Webhook Integration",": RevenueCat webhooks trigger Firebase Cloud Functions to update Firestore",[14,821,822],{},[17,823,824],{},"Time saved: 3-4 weeks",[14,826,827],{},"You don't have to read Apple's 100-page In-App Purchase guide or debug Google Play Billing errors. It just works.",[616,829,831],{"id":830},"stripe-for-web-payments","✅ Stripe for Web Payments",[14,833,834,835,838],{},"For web subscriptions and one-time payments, Template369 uses ",[17,836,837],{},"Stripe",", the most powerful payment platform for developers:",[142,840,841,847,853,859,873],{},[145,842,843,846],{},[17,844,845],{},"Stripe Checkout",": Pre-built, hosted checkout pages (or custom if you prefer)",[145,848,849,852],{},[17,850,851],{},"Subscription Management",": Recurring billing, trials, metered usage",[145,854,855,858],{},[17,856,857],{},"One-Time Payments",": For lifetime purchases or credits",[145,860,861,864,865,868,869,872],{},[17,862,863],{},"Webhook Handlers",": Firebase Cloud Functions listen for Stripe events (",[22,866,867],{},"customer.subscription.created",", ",[22,870,871],{},"invoice.paid",", etc.)",[145,874,875,878],{},[17,876,877],{},"Firestore Updates",": Payment events automatically update user records in Firestore",[14,880,881],{},[17,882,883],{},"Time saved: 2-3 weeks",[14,885,886],{},"Stripe is notoriously complex to integrate correctly. Template369 handles the heavy lifting so you can focus on your product.",[616,888,890],{"id":889},"firebase-cloud-functions-typescript-gen-2","✅ Firebase Cloud Functions (TypeScript, Gen 2)",[14,892,893,894,897],{},"The backend is where the magic happens. Template369 includes ",[17,895,896],{},"TypeScript Cloud Functions (Gen 2)"," for:",[142,899,900,906,912,918,924],{},[145,901,902,905],{},[17,903,904],{},"RevenueCat Webhooks",": When a user subscribes on iOS, Cloud Functions update their Firestore record",[145,907,908,911],{},[17,909,910],{},"Stripe Webhooks",": When a payment succeeds or fails, Cloud Functions handle it",[145,913,914,917],{},[17,915,916],{},"Subscription State Management",": Centralized logic for granting\u002Frevoking access",[145,919,920,923],{},[17,921,922],{},"Automated Notifications",": Trigger push notifications or emails based on payment events",[145,925,926,929],{},[17,927,928],{},"Security",": Server-side validation ensures client apps can't fake purchase status",[14,931,932],{},[17,933,883],{},[14,935,936],{},"No need to set up AWS Lambda, configure API Gateway, or wrestle with CORS. Firebase Cloud Functions are serverless, auto-scaling, and easy to deploy.",[616,938,940],{"id":939},"firebase-cloud-messaging-fcm-for-notifications","✅ Firebase Cloud Messaging (FCM) for Notifications",[14,942,943,944,947],{},"Stay connected with users through ",[17,945,946],{},"push notifications",":",[142,949,950,956,962,968],{},[145,951,952,955],{},[17,953,954],{},"Payment Confirmations",": \"Your subscription is now active!\"",[145,957,958,961],{},[17,959,960],{},"Payment Failures",": \"Your payment failed, please update your card.\"",[145,963,964,967],{},[17,965,966],{},"Subscription Expiry",": \"Your trial ends in 3 days.\"",[145,969,970,973],{},[17,971,972],{},"Custom Triggers",": Send notifications based on user actions or backend events",[14,975,976],{},"Template369 includes FCM integration with test flows so you can verify notifications work before launch.",[14,978,979],{},[17,980,981],{},"Time saved: 1-2 weeks",[616,983,985],{"id":984},"firestore-database-with-security-rules","✅ Firestore Database with Security Rules",[14,987,988,989,947],{},"All user data, subscription states, and payment records live in ",[17,990,991],{},"Firestore",[142,993,994,1000,1006,1012],{},[145,995,996,999],{},[17,997,998],{},"Pre-Configured Schema",": User documents, subscription fields, payment history",[145,1001,1002,1005],{},[17,1003,1004],{},"Security Rules",": Properly locked-down rules so users can't edit their own subscription status",[145,1007,1008,1011],{},[17,1009,1010],{},"Real-Time Sync",": Changes to subscription state instantly reflect in your app",[145,1013,1014,1017],{},[17,1015,1016],{},"Scalable",": Firestore scales automatically as your user base grows",[14,1019,1020],{},[17,1021,981],{},[14,1023,1024],{},"No need to design your own schema or debug security rule edge cases. It's already done.",[36,1026,1028],{"id":1027},"the-full-monetization-flow-how-it-all-works-together","The Full Monetization Flow: How It All Works Together",[14,1030,1031],{},"Here's what happens when a user subscribes in Template369:",[616,1033,1035],{"id":1034},"scenario-1-user-subscribes-on-ios","Scenario 1: User Subscribes on iOS",[382,1037,1038,1041,1047,1050,1056,1062,1071,1077],{},[145,1039,1040],{},"User taps \"Subscribe\" in your Flutter app",[145,1042,1043,1046],{},[17,1044,1045],{},"RevenueCat SDK"," handles the StoreKit purchase flow",[145,1048,1049],{},"Apple processes the payment and issues a receipt",[145,1051,1052,1055],{},[17,1053,1054],{},"RevenueCat validates the receipt"," server-side",[145,1057,1058,1061],{},[17,1059,1060],{},"RevenueCat webhook"," fires and hits your Firebase Cloud Function",[145,1063,1064,1067,1068],{},[17,1065,1066],{},"Cloud Function updates Firestore",": ",[22,1069,1070],{},"user.subscription.status = \"active\"",[145,1072,1073,1076],{},[17,1074,1075],{},"Cloud Function sends FCM notification",": \"Your subscription is active!\"",[145,1078,1079],{},"App reads Firestore and unlocks premium features",[616,1081,1083],{"id":1082},"scenario-2-user-subscribes-on-web","Scenario 2: User Subscribes on Web",[382,1085,1086,1089,1094,1097,1106,1112,1118],{},[145,1087,1088],{},"User clicks \"Subscribe\" on your web app",[145,1090,1091,1093],{},[17,1092,845],{}," opens and user enters payment details",[145,1095,1096],{},"Stripe processes the payment",[145,1098,1099,1102,1103,1105],{},[17,1100,1101],{},"Stripe webhook"," fires (",[22,1104,867],{},")",[145,1107,1108,1067,1110],{},[17,1109,1066],{},[22,1111,1070],{},[145,1113,1114,1117],{},[17,1115,1116],{},"Cloud Function sends email confirmation"," (optional)",[145,1119,1120],{},"Web app refreshes and shows premium features",[616,1122,1124],{"id":1123},"scenario-3-subscription-renewal-ios-or-web","Scenario 3: Subscription Renewal (iOS or Web)",[382,1126,1127,1130,1136,1144,1149],{},[145,1128,1129],{},"Apple or Stripe automatically charges the user",[145,1131,1132,1135],{},[17,1133,1134],{},"Webhook fires"," with renewal confirmation",[145,1137,1138,1067,1141],{},[17,1139,1140],{},"Cloud Function extends subscription",[22,1142,1143],{},"user.subscription.expiresAt = new Date() + 30 days",[145,1145,1146],{},[17,1147,1148],{},"Cloud Function sends \"Thanks for renewing!\" notification",[145,1150,1151],{},"User keeps access without interruption",[616,1153,1155],{"id":1154},"scenario-4-payment-failure","Scenario 4: Payment Failure",[382,1157,1158,1161,1166,1173,1178],{},[145,1159,1160],{},"Payment fails (expired card, insufficient funds, etc.)",[145,1162,1163,1165],{},[17,1164,1134],{}," with failure event",[145,1167,1168,1067,1170],{},[17,1169,1066],{},[22,1171,1172],{},"user.subscription.status = \"past_due\"",[145,1174,1175,1177],{},[17,1176,1075],{},": \"Please update your payment method\"",[145,1179,1180],{},"App shows a banner prompting user to fix payment",[14,1182,1183,1186],{},[17,1184,1185],{},"All of this is built and tested in Template369."," You just customize the messaging and branding.",[36,1188,1190],{"id":1189},"what-this-means-for-you-ship-faster-earn-revenue-sooner","What This Means for You: Ship Faster, Earn Revenue Sooner",[616,1192,1194],{"id":1193},"before-template369","Before Template369:",[142,1196,1197,1200,1203,1206,1209],{},[145,1198,1199],{},"Spend 4-6 weeks reading docs, integrating SDKs, and debugging webhooks",[145,1201,1202],{},"Hire a backend developer to build Cloud Functions",[145,1204,1205],{},"Test edge cases (trials, refunds, grace periods)",[145,1207,1208],{},"Hope you didn't miss a security hole",[145,1210,1211,1214],{},[17,1212,1213],{},"Total cost",": $20,000-$40,000 in developer time",[616,1216,1218],{"id":1217},"with-template369","With Template369:",[142,1220,1221,1228,1231,1234,1237],{},[145,1222,1223,1224,1227],{},"Get the template for ",[17,1225,1226],{},"$350 a year"," (or $34.99 a month)",[145,1229,1230],{},"Configure your RevenueCat and Stripe accounts (1-2 hours)",[145,1232,1233],{},"Deploy Cloud Functions to Firebase (30 minutes)",[145,1235,1236],{},"Customize pricing tiers and branding (1-2 days)",[145,1238,1239],{},[17,1240,1241],{},"Launch in under a week",[14,1243,1244],{},[17,1245,1246],{},"Savings: $20,000-$40,000 and 4-6 weeks",[36,1248,1250],{"id":1249},"who-is-this-for","Who Is This For?",[14,1252,1253],{},"Template369's monetization stack is perfect if you're:",[142,1255,1256,1262,1268,1274,1280],{},[145,1257,1258,1261],{},[17,1259,1260],{},"Building a SaaS app"," with subscriptions on iOS, Android, and web",[145,1263,1264,1267],{},[17,1265,1266],{},"An indie developer"," who wants to monetize without hiring a backend team",[145,1269,1270,1273],{},[17,1271,1272],{},"A startup"," that needs to prove revenue ASAP",[145,1275,1276,1279],{},[17,1277,1278],{},"An agency"," delivering client projects with payment integration",[145,1281,1282,1285],{},[17,1283,1284],{},"A technical founder"," who'd rather focus on features than payment plumbing",[14,1287,1288],{},"If your app needs to make money across multiple platforms, this is your shortcut.",[36,1290,1292],{"id":1291},"included-full-documentation-support","Included: Full Documentation & Support",[14,1294,1295,1296,1299,1300,947],{},"You're not just getting code, you're getting ",[17,1297,1298],{},"step-by-step guides"," at ",[131,1301,1304],{"href":1302,"rel":1303},"https:\u002F\u002Fdocs.template369.com",[135],"docs.template369.com",[142,1306,1307,1313,1319,1325,1331,1337],{},[145,1308,1309,1312],{},[17,1310,1311],{},"RevenueCat Setup",": Create account, configure products, integrate SDK",[145,1314,1315,1318],{},[17,1316,1317],{},"Stripe Setup",": Set up Checkout, configure webhooks, test payments",[145,1320,1321,1324],{},[17,1322,1323],{},"Cloud Functions Deployment",": Deploy, configure secrets, test webhooks",[145,1326,1327,1330],{},[17,1328,1329],{},"Firestore Configuration",": Schema explanation, security rules walkthrough",[145,1332,1333,1336],{},[17,1334,1335],{},"FCM Testing",": Send test notifications, verify delivery",[145,1338,1339,1342],{},[17,1340,1341],{},"Component Library",": Pre-built payment screens and UI elements",[14,1344,1345],{},"Everything is documented, tested, and ready to customize.",[36,1347,1349],{"id":1348},"real-world-use-cases","Real-World Use Cases",[616,1351,1353],{"id":1352},"saas-app-with-freemium-model","SaaS App with Freemium Model",[142,1355,1356,1359,1362,1365,1368],{},[145,1357,1358],{},"Free tier with limited features",[145,1360,1361],{},"Premium subscription unlocks full access",[145,1363,1364],{},"RevenueCat handles mobile subscriptions",[145,1366,1367],{},"Stripe handles web subscriptions",[145,1369,1370],{},"Firestore syncs state across platforms",[616,1372,1374],{"id":1373},"fitness-app-with-monthly-coaching","Fitness App with Monthly Coaching",[142,1376,1377,1380,1383,1386,1389],{},[145,1378,1379],{},"Users subscribe for $9.99\u002Fmonth",[145,1381,1382],{},"iOS and Android users pay via App Store \u002F Google Play",[145,1384,1385],{},"Web users pay via Stripe",[145,1387,1388],{},"Cloud Functions unlock access to coaching content",[145,1390,1391],{},"FCM sends workout reminders",[616,1393,1395],{"id":1394},"productivity-tool-with-lifetime-purchase","Productivity Tool with Lifetime Purchase",[142,1397,1398,1401,1404,1407,1410],{},[145,1399,1400],{},"Users can buy lifetime access for $49.99",[145,1402,1403],{},"RevenueCat handles mobile purchases",[145,1405,1406],{},"Stripe handles web purchases",[145,1408,1409],{},"Firestore grants permanent premium status",[145,1411,1412],{},"No recurring billing complexity",[36,1414,1416],{"id":1415},"the-template369-advantage-production-ready-not-a-tutorial","The Template369 Advantage: Production-Ready, Not a Tutorial",[14,1418,1419],{},"Most payment tutorials and templates are \"hello world\" examples that break in production. Template369 is different:",[142,1421,1422,1428,1434,1440,1445],{},[145,1423,1424,1427],{},[17,1425,1426],{},"Battle-Tested",": Used by real apps in production",[145,1429,1430,1433],{},[17,1431,1432],{},"Complete",": Not just the happy path, handles failures, refunds, edge cases",[145,1435,1436,1439],{},[17,1437,1438],{},"Secure",": Server-side validation, proper security rules, webhook verification",[145,1441,1442,1444],{},[17,1443,1016],{},": Built on Firebase, which scales automatically",[145,1446,1447,1450],{},[17,1448,1449],{},"Maintained",": Modern architecture with TypeScript Cloud Functions Gen 2",[14,1452,1453],{},"You're getting production-grade code, not a toy example.",[36,1455,1457],{"id":1456},"stop-reinventing-the-wheel-start-earning-revenue","Stop Reinventing the Wheel, Start Earning Revenue",[14,1459,1460],{},"Payment integration is a solved problem. You shouldn't spend weeks rebuilding what already exists.",[14,1462,1463],{},"Template369 gives you the complete monetization stack, RevenueCat, Stripe, Firebase Cloud Functions, Firestore, and FCM, all integrated, tested, and documented.",[14,1465,1466,1467,1469],{},"For ",[17,1468,1226],{}," (or $34.99 a month), you get:",[142,1471,1472,1475,1478,1481,1484],{},[145,1473,1474],{},"✅ Cross-platform payment integration (iOS, Android, web, macOS)",[145,1476,1477],{},"✅ Backend infrastructure (Cloud Functions, webhooks, Firestore)",[145,1479,1480],{},"✅ Subscription lifecycle management",[145,1482,1483],{},"✅ Push notifications tied to payment events",[145,1485,1486],{},"✅ Full documentation and setup guides",[14,1488,1489],{},[17,1490,1491],{},"Skip 1000+ hours of integration work. Launch this month. Start earning revenue next week.",[36,1493,1495],{"id":1494},"get-template369-today",[131,1496,1498],{"href":604,"rel":1497},[135],"Get Template369 Today",[14,1500,1501,1502,1506],{},"Ready to add payments to your Flutter app without the headache? Check out the ",[131,1503,1505],{"href":1302,"rel":1504},[135],"Template369 docs"," to see the complete feature list, or grab the template and start building today.",[14,1508,1509,1510,1515],{},"Have questions about integrating payments into your app? ",[131,1511,1514],{"href":1512,"rel":1513},"https:\u002F\u002Fapp369.com\u002Fcontact",[135],"Contact App369",", I'm here to help you ship faster.",[1517,1518],"hr",{},[36,1520,1522],{"id":1521},"frequently-asked-questions","Frequently Asked Questions",[14,1524,1525,1528],{},[17,1526,1527],{},"What payment platforms does Template369 support?","\nTemplate369 integrates RevenueCat for iOS, Android, and macOS in-app purchases, plus Stripe for web subscriptions and one-time payments.",[14,1530,1531,1534],{},[17,1532,1533],{},"How long does it take to integrate payments with Template369?","\nWith Template369, payment integration takes 1-2 days for configuration compared to the 4-6 weeks typical of custom builds.",[14,1536,1537,1540],{},[17,1538,1539],{},"Does Template369 handle subscription management?","\nTemplate369 includes complete subscription lifecycle management covering free trials, renewals, cancellations, grace periods, refunds, and payment failures.",[14,1542,1543,1546],{},[17,1544,1545],{},"Is the payment integration secure?","\nTemplate369 implements PCI DSS-compliant security through Stripe's certified Level 1 service provider infrastructure and official App Store\u002FGoogle Play SDKs. The OWASP Foundation's 2024 guidelines rank server-side receipt validation and webhook verification as essential security practices, both of which Template369 enforces through Firebase Cloud Functions and security rules.",[14,1548,1549,1552],{},[17,1550,1551],{},"Can I use Template369 for both subscriptions and one-time purchases?","\nTemplate369 supports subscriptions (monthly\u002Fyearly), one-time purchases, lifetime access, and metered usage models.",[14,1554,1555,1558],{},[17,1556,1557],{},"What happens when a payment fails in Template369?","\nTemplate369's Cloud Functions automatically handle payment failures by updating Firestore subscription status, sending FCM push notifications, and managing retry grace periods.",[14,1560,1561,1564],{},[17,1562,1563],{},"Do I need a backend developer to use Template369 payments?","\nNo backend developer is required. Template369 includes pre-built TypeScript Firebase Cloud Functions (Gen 2) handling all server-side logic including webhooks, subscription updates, notifications, and database sync.",[14,1566,1567,1570,1571,1576],{},[17,1568,1569],{},"How much does Template369 save compared to building payments from scratch?","\nTemplate369 costs $350 a year or $34.99 a month (",[131,1572,1575],{"href":1573,"rel":1574},"https:\u002F\u002Ftemplate369.com\u002F#pricing",[135],"pricing",") and includes the complete payment stack, so you skip writing the integration yourself.",{"title":462,"searchDepth":463,"depth":463,"links":1578},[1579,1587,1594,1600,1604,1605,1606,1611,1612,1613,1614],{"id":610,"depth":463,"text":611,"children":1580},[1581,1583,1584,1585,1586],{"id":618,"depth":1582,"text":619},3,{"id":653,"depth":1582,"text":654},{"id":677,"depth":1582,"text":678},{"id":707,"depth":1582,"text":708},{"id":731,"depth":1582,"text":732},{"id":761,"depth":463,"text":762,"children":1588},[1589,1590,1591,1592,1593],{"id":772,"depth":1582,"text":773},{"id":830,"depth":1582,"text":831},{"id":889,"depth":1582,"text":890},{"id":939,"depth":1582,"text":940},{"id":984,"depth":1582,"text":985},{"id":1027,"depth":463,"text":1028,"children":1595},[1596,1597,1598,1599],{"id":1034,"depth":1582,"text":1035},{"id":1082,"depth":1582,"text":1083},{"id":1123,"depth":1582,"text":1124},{"id":1154,"depth":1582,"text":1155},{"id":1189,"depth":463,"text":1190,"children":1601},[1602,1603],{"id":1193,"depth":1582,"text":1194},{"id":1217,"depth":1582,"text":1218},{"id":1249,"depth":463,"text":1250},{"id":1291,"depth":463,"text":1292},{"id":1348,"depth":463,"text":1349,"children":1607},[1608,1609,1610],{"id":1352,"depth":1582,"text":1353},{"id":1373,"depth":1582,"text":1374},{"id":1394,"depth":1582,"text":1395},{"id":1415,"depth":463,"text":1416},{"id":1456,"depth":463,"text":1457},{"id":1494,"depth":463,"text":1498},{"id":1521,"depth":463,"text":1522},"Mobile Apps","2025-12-05T10:00:00.000Z","Get a pre-built RevenueCat, Stripe, and Firebase monetization stack with Template369. Skip months of payment integration work and start earning revenue faster.",{"readingTimeStats":1619},{"text":1620,"minutes":1621,"time":1622,"words":1623},"9 min read",8.775,526500,1755,"\u002Fblog\u002Frevenuecat-stripe-firebase-monetization-stack-template369","8 min",{"title":541,"description":1617},"blog\u002Frevenuecat-stripe-firebase-monetization-stack-template369","RevenueCat integration, Stripe firebase integration, flutter payment template, mobile app monetization, in-app purchase boilerplate, flutter stripe template, firebase cloud functions, app subscription template, cross-platform payments, mobile payment integration, template369, flutter monetization","2026-10-12T12:00:00.000Z","https:\u002F\u002Fapp369.com\u002Fblog\u002Frevenuecat-stripe-firebase-monetization-stack-template369\u002F","5ICCvnpoC66K1I5LfnI7CG8Ze3xahhmO0A66_BkN9Wc",{"id":1633,"title":1634,"author":1635,"body":1637,"category":470,"createdAt":2274,"description":2275,"disclosure":473,"extension":474,"faq":2276,"howTo":473,"lastVerified":473,"location":494,"meta":2292,"navigation":501,"ogImage":473,"path":2297,"primaryKeyword":2298,"readingTime":504,"related":2299,"seo":2302,"sources":2303,"stem":2318,"tags":2319,"takeaways":2320,"updatedAt":2274,"url":2326,"__hash__":2327},"blog\u002Fblog\u002Fflutter-gradle-plugin-applied-imperatively-fix-2026.md","Flutter \"Applying Gradle Plugin Imperatively\" Error: The Fix",{"name":7,"social":1636},{"twitter":9},{"type":11,"value":1638,"toc":2259},[1639,1653,1656,1661,1665,1760,1763,1767,1770,1794,1797,1801,1813,1817,1836,1840,1851,2005,2017,2021,2038,2042,2060,2080,2083,2111,2133,2137,2144,2148,2151,2223,2226,2230,2246,2248,2255],[14,1640,1641,1644,1645,1648,1649,1652],{},[17,1642,1643],{},"If an Android build fails with \"You are applying Flutter's main Gradle plugin imperatively using the apply script method, which is not possible anymore\", your Gradle files still load Flutter the pre-3.16 way."," Flutter 3.29 removed support for that method, so the old ",[22,1646,1647],{},"flutter.gradle"," file now does nothing but throw this error. The fix is to move three Gradle files to the declarative ",[22,1650,1651],{},"plugins {}"," block. It changes how the build is wired, not your app's code.",[14,1654,1655],{},"If you landed here from the link in the error message, flutter.dev\u002Fto\u002Fflutter-gradle-plugin-apply, it still opens Flutter's migration page. This guide follows that page and adds what the page doesn't say: when the old method stopped working, and the Firebase case most older apps have. The facts come from Flutter's docs, its source code and its release archive, as listed in the sources. I checked each one on October 18, 2026.",[14,1657,1658,1660],{},[17,1659,33],{}," App369 is my studio. I build and fix Flutter apps, and the last section mentions what I sell. Google doesn't pay me for anything on this page.",[36,1662,1664],{"id":1663},"what-changed-and-when","What changed, and when",[44,1666,1667,1680],{},[47,1668,1669],{},[50,1670,1671,1674,1677],{},[53,1672,1673],{},"Date",[53,1675,1676],{},"What happened",[53,1678,1679],{},"Source",[63,1681,1682,1708,1724,1739],{},[50,1683,1684,1687,1697],{},[68,1685,1686],{},"November 15, 2023",[68,1688,1689,1690,1692,1693,1696],{},"Flutter 3.16 adds support for the declarative ",[22,1691,1651],{}," block. New ",[22,1694,1695],{},"flutter create"," projects use it",[68,1698,1699,868,1704],{},[131,1700,1703],{"href":1701,"rel":1702},"https:\u002F\u002Fdocs.flutter.dev\u002Frelease\u002Fbreaking-changes\u002Fflutter-gradle-plugin-apply",[135],"Flutter docs",[131,1705,1707],{"href":527,"rel":1706},[135],"release archive",[50,1709,1710,1713,1716],{},[68,1711,1712],{},"February 15, 2024",[68,1714,1715],{},"Flutter 3.19: the declarative block is the recommended way",[68,1717,1718,868,1721],{},[131,1719,1703],{"href":1701,"rel":1720},[135],[131,1722,1707],{"href":527,"rel":1723},[135],[50,1725,1726,1729,1732],{},[68,1727,1728],{},"January 7, 2025",[68,1730,1731],{},"Pull request #160947 removes support for the imperative apply",[68,1733,1734],{},[131,1735,1738],{"href":1736,"rel":1737},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fpull\u002F160947",[135],"Flutter PR #160947",[50,1740,1741,1746,1751],{},[68,1742,1743],{},[17,1744,1745],{},"February 12, 2025",[68,1747,1748],{},[17,1749,1750],{},"Flutter 3.29.0, the first stable release that includes that change",[68,1752,1753,868,1757],{},[131,1754,1756],{"href":527,"rel":1755},[135],"Release archive",[131,1758,1738],{"href":1736,"rel":1759},[135],[14,1761,1762],{},"Flutter's docs page lists only when the new method was supported and recommended. The removal date comes from the pull request. I checked that its commit is in the 3.29.0 tag and not in 3.27.",[616,1764,1766],{"id":1765},"the-two-versions-of-the-error","The two versions of the error",[14,1768,1769],{},"Both come from files in Flutter's own Gradle folder that now exist only to throw an error:",[142,1771,1772,1784],{},[145,1773,1774,1776,1777,1780,1781,424],{},[22,1775,1647],{},": \"You are applying Flutter's main Gradle plugin imperatively using the apply script method, which is not possible anymore.\" This means ",[22,1778,1779],{},"android\u002Fapp\u002Fbuild.gradle"," still has ",[22,1782,1783],{},"apply from: \"...\u002Fflutter.gradle\"",[145,1785,1786,1789,1790,1793],{},[22,1787,1788],{},"app_plugin_loader.gradle",": \"You are applying Flutter's app_plugin_loader Gradle plugin imperatively using the apply script method, which is not possible anymore.\" This means ",[22,1791,1792],{},"android\u002Fsettings.gradle"," still loads the plugin loader the old way.",[14,1795,1796],{},"Both point to the same migration page, and the fix below covers both.",[36,1798,1800],{"id":1799},"the-fix-file-by-file","The fix, file by file",[14,1802,1803,1804,1808,1809,1812],{},"These steps follow Flutter's ",[131,1805,1807],{"href":1701,"rel":1806},[135],"migration page",". My advice: commit or back up the ",[22,1810,1811],{},"android"," folder before you start, so you can compare.",[616,1814,1816],{"id":1815},"_1-note-your-agp-and-kotlin-versions","1. Note your AGP and Kotlin versions",[14,1818,1819,1820,1823,1824,1827,1828,1831,1832,1835],{},"Open ",[22,1821,1822],{},"android\u002Fbuild.gradle",". In the ",[22,1825,1826],{},"buildscript"," block, the Android Gradle Plugin version is the number at the end of ",[22,1829,1830],{},"classpath 'com.android.tools.build:gradle:...'",", and the Kotlin version is in ",[22,1833,1834],{},"ext.kotlin_version = '...'",". You need both in the next step.",[616,1837,1839],{"id":1838},"_2-replace-androidsettingsgradle","2. Replace android\u002Fsettings.gradle",[14,1841,1842,1843,1846,1847,1850],{},"Flutter's page gives this as the new contents. Replace ",[22,1844,1845],{},"{agpVersion}"," and ",[22,1848,1849],{},"{kotlinVersion}"," with the versions from step 1:",[1852,1853,1857],"pre",{"className":1854,"code":1855,"language":1856,"meta":462,"style":462},"language-groovy shiki shiki-themes github-light github-dark","pluginManagement {\n    def flutterSdkPath = {\n        def properties = new Properties()\n        file(\"local.properties\").withInputStream { properties.load(it) }\n        def flutterSdkPath = properties.getProperty(\"flutter.sdk\")\n        assert flutterSdkPath != null, \"flutter.sdk not set in local.properties\"\n        return flutterSdkPath\n    }()\n\n    includeBuild(\"$flutterSdkPath\u002Fpackages\u002Fflutter_tools\u002Fgradle\")\n\n    repositories {\n        google()\n        mavenCentral()\n        gradlePluginPortal()\n    }\n}\n\nplugins {\n    id \"dev.flutter.flutter-plugin-loader\" version \"1.0.0\"\n    id \"com.android.application\" version \"{agpVersion}\" apply false\n    id \"org.jetbrains.kotlin.android\" version \"{kotlinVersion}\" apply false\n}\n\ninclude \":app\"\n","groovy",[22,1858,1859,1867,1872,1877,1883,1889,1895,1901,1907,1913,1919,1924,1930,1936,1942,1948,1954,1960,1965,1971,1977,1983,1989,1994,1999],{"__ignoreMap":462},[1860,1861,1864],"span",{"class":1862,"line":1863},"line",1,[1860,1865,1866],{},"pluginManagement {\n",[1860,1868,1869],{"class":1862,"line":463},[1860,1870,1871],{},"    def flutterSdkPath = {\n",[1860,1873,1874],{"class":1862,"line":1582},[1860,1875,1876],{},"        def properties = new Properties()\n",[1860,1878,1880],{"class":1862,"line":1879},4,[1860,1881,1882],{},"        file(\"local.properties\").withInputStream { properties.load(it) }\n",[1860,1884,1886],{"class":1862,"line":1885},5,[1860,1887,1888],{},"        def flutterSdkPath = properties.getProperty(\"flutter.sdk\")\n",[1860,1890,1892],{"class":1862,"line":1891},6,[1860,1893,1894],{},"        assert flutterSdkPath != null, \"flutter.sdk not set in local.properties\"\n",[1860,1896,1898],{"class":1862,"line":1897},7,[1860,1899,1900],{},"        return flutterSdkPath\n",[1860,1902,1904],{"class":1862,"line":1903},8,[1860,1905,1906],{},"    }()\n",[1860,1908,1910],{"class":1862,"line":1909},9,[1860,1911,1912],{"emptyLinePlaceholder":501},"\n",[1860,1914,1916],{"class":1862,"line":1915},10,[1860,1917,1918],{},"    includeBuild(\"$flutterSdkPath\u002Fpackages\u002Fflutter_tools\u002Fgradle\")\n",[1860,1920,1922],{"class":1862,"line":1921},11,[1860,1923,1912],{"emptyLinePlaceholder":501},[1860,1925,1927],{"class":1862,"line":1926},12,[1860,1928,1929],{},"    repositories {\n",[1860,1931,1933],{"class":1862,"line":1932},13,[1860,1934,1935],{},"        google()\n",[1860,1937,1939],{"class":1862,"line":1938},14,[1860,1940,1941],{},"        mavenCentral()\n",[1860,1943,1945],{"class":1862,"line":1944},15,[1860,1946,1947],{},"        gradlePluginPortal()\n",[1860,1949,1951],{"class":1862,"line":1950},16,[1860,1952,1953],{},"    }\n",[1860,1955,1957],{"class":1862,"line":1956},17,[1860,1958,1959],{},"}\n",[1860,1961,1963],{"class":1862,"line":1962},18,[1860,1964,1912],{"emptyLinePlaceholder":501},[1860,1966,1968],{"class":1862,"line":1967},19,[1860,1969,1970],{},"plugins {\n",[1860,1972,1974],{"class":1862,"line":1973},20,[1860,1975,1976],{},"    id \"dev.flutter.flutter-plugin-loader\" version \"1.0.0\"\n",[1860,1978,1980],{"class":1862,"line":1979},21,[1860,1981,1982],{},"    id \"com.android.application\" version \"{agpVersion}\" apply false\n",[1860,1984,1986],{"class":1862,"line":1985},22,[1860,1987,1988],{},"    id \"org.jetbrains.kotlin.android\" version \"{kotlinVersion}\" apply false\n",[1860,1990,1992],{"class":1862,"line":1991},23,[1860,1993,1959],{},[1860,1995,1997],{"class":1862,"line":1996},24,[1860,1998,1912],{"emptyLinePlaceholder":501},[1860,2000,2002],{"class":1862,"line":2001},25,[1860,2003,2004],{},"include \":app\"\n",[14,2006,2007,2008,1846,2011,2013,2014,424],{},"If you had your own code in this file, keep it after the ",[22,2009,2010],{},"pluginManagement {}",[22,2012,1651],{}," blocks. Gradle doesn't allow other code before them. The plugin loader must not be set to ",[22,2015,2016],{},"apply false",[616,2018,2020],{"id":2019},"_3-remove-buildscript-from-androidbuildgradle","3. Remove buildscript from android\u002Fbuild.gradle",[14,2022,2023,2024,2027,2028,868,2031,1846,2034,2037],{},"Delete the whole ",[22,2025,2026],{},"buildscript { ... }"," block. The ",[22,2029,2030],{},"allprojects",[22,2032,2033],{},"subprojects",[22,2035,2036],{},"clean"," parts stay.",[616,2039,2041],{"id":2040},"_4-update-androidappbuildgradle","4. Update android\u002Fapp\u002Fbuild.gradle",[14,2043,2044,2045,2048,2049,2052,2053,2056,2057,2059],{},"Remove the ",[22,2046,2047],{},"def flutterRoot = localProperties.getProperty('flutter.sdk')"," line and the ",[22,2050,2051],{},"if (flutterRoot == null) { throw ... }"," block that follows it. Keep the code that loads ",[22,2054,2055],{},"local.properties",", which the version settings still use. Then remove the old apply lines. In Flutter 3.10's ",[22,2058,1695],{}," template they look like this:",[1852,2061,2063],{"className":1854,"code":2062,"language":1856,"meta":462,"style":462},"apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply from: \"$flutterRoot\u002Fpackages\u002Fflutter_tools\u002Fgradle\u002Fflutter.gradle\"\n",[22,2064,2065,2070,2075],{"__ignoreMap":462},[1860,2066,2067],{"class":1862,"line":1863},[1860,2068,2069],{},"apply plugin: 'com.android.application'\n",[1860,2071,2072],{"class":1862,"line":463},[1860,2073,2074],{},"apply plugin: 'kotlin-android'\n",[1860,2076,2077],{"class":1862,"line":1582},[1860,2078,2079],{},"apply from: \"$flutterRoot\u002Fpackages\u002Fflutter_tools\u002Fgradle\u002Fflutter.gradle\"\n",[14,2081,2082],{},"Then add this at the very top of the file:",[1852,2084,2086],{"className":1854,"code":2085,"language":1856,"meta":462,"style":462},"plugins {\n    id \"com.android.application\"\n    id \"kotlin-android\"\n    id \"dev.flutter.flutter-gradle-plugin\"\n}\n",[22,2087,2088,2092,2097,2102,2107],{"__ignoreMap":462},[1860,2089,2090],{"class":1862,"line":1863},[1860,2091,1970],{},[1860,2093,2094],{"class":1862,"line":463},[1860,2095,2096],{},"    id \"com.android.application\"\n",[1860,2098,2099],{"class":1862,"line":1582},[1860,2100,2101],{},"    id \"kotlin-android\"\n",[1860,2103,2104],{"class":1862,"line":1879},[1860,2105,2106],{},"    id \"dev.flutter.flutter-gradle-plugin\"\n",[1860,2108,2109],{"class":1862,"line":1885},[1860,2110,1959],{},[14,2112,2113,2114,2117,2118,393,2121,2124,2125,2128,2129,2132],{},"Flutter's page points out that ",[22,2115,2116],{},"dev.flutter.flutter-gradle-plugin"," here is a different ID from ",[22,2119,2120],{},"dev.flutter.flutter-plugin-loader",[22,2122,2123],{},"settings.gradle",". If the ",[22,2126,2127],{},"dependencies"," block has ",[22,2130,2131],{},"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version",", remove that line.",[616,2134,2136],{"id":2135},"_5-build-and-run","5. Build and run",[14,2138,2139,2140,2143],{},"Flutter's page says to run ",[22,2141,2142],{},"flutter run"," and check that the app builds and launches on an Android device or emulator.",[36,2145,2147],{"id":2146},"if-the-app-uses-firebase","If the app uses Firebase",[14,2149,2150],{},"If your app uses Firebase, its Google Services plugin, and Crashlytics if you use it, are probably applied the old way too. Flutter's page covers this case:",[382,2152,2153,2170,2181,2208],{},[145,2154,2155,2156,2158,2159,2162,2163,1846,2166,2169],{},"In ",[22,2157,1822],{},", remove the ",[22,2160,2161],{},"classpath"," lines for ",[22,2164,2165],{},"com.google.gms:google-services",[22,2167,2168],{},"com.google.firebase:firebase-crashlytics-gradle",". Note their versions first.",[145,2171,2155,2172,2174,2175,1846,2178,424],{},[22,2173,1779],{},", remove ",[22,2176,2177],{},"apply plugin: 'com.google.gms.google-services'",[22,2179,2180],{},"apply plugin: 'com.google.firebase.crashlytics'",[145,2182,2183,2184,2187,2188,2190,2191,947,2193],{},"Add both to the ",[22,2185,2186],{},"plugins"," block in ",[22,2189,1792],{},", with the versions you noted and ",[22,2192,2016],{},[1852,2194,2196],{"className":1854,"code":2195,"language":1856,"meta":462,"style":462},"id \"com.google.gms.google-services\" version \"4.4.0\" apply false\nid \"com.google.firebase.crashlytics\" version \"2.9.9\" apply false\n",[22,2197,2198,2203],{"__ignoreMap":462},[1860,2199,2200],{"class":1862,"line":1863},[1860,2201,2202],{},"id \"com.google.gms.google-services\" version \"4.4.0\" apply false\n",[1860,2204,2205],{"class":1862,"line":463},[1860,2206,2207],{},"id \"com.google.firebase.crashlytics\" version \"2.9.9\" apply false\n",[145,2209,2210,2211,1846,2214,2217,2218,2187,2220,2222],{},"Add ",[22,2212,2213],{},"id \"com.google.gms.google-services\"",[22,2215,2216],{},"id \"com.google.firebase.crashlytics\""," to the ",[22,2219,2186],{},[22,2221,1779],{},", without versions.",[14,2224,2225],{},"The versions above are the ones in Flutter's example. Use the versions your project had, or newer ones.",[36,2227,2229],{"id":2228},"if-the-build-still-fails-after-this","If the build still fails after this",[14,2231,2232,2233,2237,2238,2241,2242,424],{},"In my view, a project old enough to hit this error usually has more than one problem waiting: old plugins, an old AGP or Gradle version, or the v1 embedding. If the next error says \"Build failed due to use of deleted Android v1 embedding\", see ",[131,2234,2236],{"href":2235},"\u002Fblog\u002Fflutter-deleted-android-v1-embedding-build-failed-2026\u002F","the v1 embedding fix",", also removed in Flutter 3.29. If Gradle can't find ",[22,2239,2240],{},"jcenter()",", see ",[131,2243,2245],{"href":2244},"\u002Fblog\u002Fjcenter-bintray-shut-down-fix-android-flutter-builds-2026\u002F","the JCenter guide",[36,2247,448],{"id":447},[14,2249,2250,2251,456,2253,424],{},"If an older Flutter app won't build after an upgrade, the ",[131,2252,455],{"href":454},[131,2254,460],{"href":459},[2256,2257,2258],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":462,"searchDepth":463,"depth":463,"links":2260},[2261,2264,2271,2272,2273],{"id":1663,"depth":463,"text":1664,"children":2262},[2263],{"id":1765,"depth":1582,"text":1766},{"id":1799,"depth":463,"text":1800,"children":2265},[2266,2267,2268,2269,2270],{"id":1815,"depth":1582,"text":1816},{"id":1838,"depth":1582,"text":1839},{"id":2019,"depth":1582,"text":2020},{"id":2040,"depth":1582,"text":2041},{"id":2135,"depth":1582,"text":2136},{"id":2146,"depth":463,"text":2147},{"id":2228,"depth":463,"text":2229},{"id":447,"depth":463,"text":448},"2026-10-18T23:00:00.000Z","Since Flutter 3.29 (February 12, 2025), an Android build that still uses apply from: flutter.gradle fails with \"You are applying Flutter's main Gradle plugin imperatively using the apply script method, which is not possible anymore.\" How to move settings.gradle, build.gradle and app\u002Fbuild.gradle to the plugins {} block, from Flutter's docs and source checked October 18, 2026.",[2277,2280,2283,2286,2289],{"question":2278,"answer":2279},"What does \"applying Flutter's main Gradle plugin imperatively\" mean?","Your android\u002Fapp\u002Fbuild.gradle still loads Flutter's Gradle plugin with apply from: \"$flutterRoot\u002Fpackages\u002Fflutter_tools\u002Fgradle\u002Fflutter.gradle\". Flutter removed support for that method, and in Flutter 3.29 and later that file only throws this error. The fix is to apply the plugin with the declarative plugins {} block.",{"question":2281,"answer":2282},"Which Flutter version made the imperative apply an error?","Flutter 3.29. The change that removed support, Flutter pull request #160947, was merged on January 7, 2025 and is included in the 3.29.0 tag but not in 3.27. Flutter's release archive dates 3.29.0 February 12, 2025.",{"question":2284,"answer":2285},"How do I fix the error?","Follow Flutter's \"Deprecated imperative apply of Flutter's Gradle plugins\" page: put a pluginManagement block and a plugins block with dev.flutter.flutter-plugin-loader in android\u002Fsettings.gradle, remove the buildscript block from android\u002Fbuild.gradle, and replace the apply lines in android\u002Fapp\u002Fbuild.gradle with a plugins block that includes dev.flutter.flutter-gradle-plugin.",{"question":2287,"answer":2288},"What is the difference between flutter-plugin-loader and flutter-gradle-plugin?","Flutter's docs say dev.flutter.flutter-plugin-loader is the settings plugin and goes in settings.gradle, while dev.flutter.flutter-gradle-plugin is the project plugin and goes in app\u002Fbuild.gradle. They are different IDs, and the loader must not be set to apply false.",{"question":2290,"answer":2291},"What about google-services and Crashlytics?","Flutter's docs show removing their classpath lines from android\u002Fbuild.gradle and their apply plugin lines from app\u002Fbuild.gradle, then adding com.google.gms.google-services and com.google.firebase.crashlytics with versions and apply false to the settings.gradle plugins block, and without versions to the app\u002Fbuild.gradle plugins block.",{"readingTimeStats":2293},{"text":497,"minutes":2294,"time":2295,"words":2296},4.295,257700,859,"\u002Fblog\u002Fflutter-gradle-plugin-applied-imperatively-fix-2026","applying flutter's main gradle plugin imperatively",[508,2300,2301],"jcenter-bintray-shut-down-fix-android-flutter-builds-2026","flutter-ios-build-failed-after-upgrade-2026",{"title":1634,"description":2275},[2304,2306,2308,2311,2314,2317],{"title":2305,"url":1701},"Flutter docs, Deprecated imperative apply of Flutter's Gradle plugins (last updated July 31, 2026)",{"title":2307,"url":1736},"Flutter on GitHub, pull request #160947 \"Remove support for imperative apply of Flutter Gradle Plugin\"",{"title":2309,"url":2310},"Flutter on GitHub, flutter_tools gradle\u002Fflutter.gradle","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002Fmaster\u002Fpackages\u002Fflutter_tools\u002Fgradle\u002Fflutter.gradle",{"title":2312,"url":2313},"Flutter on GitHub, flutter_tools gradle\u002Fapp_plugin_loader.gradle","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002Fmaster\u002Fpackages\u002Fflutter_tools\u002Fgradle\u002Fapp_plugin_loader.gradle",{"title":2315,"url":2316},"Flutter on GitHub, Flutter 3.10.0 app\u002Fbuild.gradle template","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002F3.10.0\u002Fpackages\u002Fflutter_tools\u002Ftemplates\u002Fapp_shared\u002Fandroid-kotlin.tmpl\u002Fapp\u002Fbuild.gradle.tmpl",{"title":526,"url":527},"blog\u002Fflutter-gradle-plugin-applied-imperatively-fix-2026","applying flutter main gradle plugin imperatively, apply script method not possible anymore, flutter gradle plugin declarative, dev.flutter.flutter-gradle-plugin, dev.flutter.flutter-plugin-loader, app_plugin_loader gradle imperatively, flutter 3.29 android build error, flutter settings.gradle pluginManagement, google-services plugins block flutter",[2321,2322,2323,2324,2325],"Flutter 3.16 added support for applying its Gradle plugins with the declarative plugins {} block, and Flutter 3.19 made it the recommended way. Projects created before 3.16 have to be migrated by hand.","Flutter removed support for the old apply from: flutter.gradle method in pull request #160947, merged January 7, 2025. Flutter 3.29.0, released February 12, 2025, is the first stable release that includes it.","The build now stops with \"You are applying Flutter's main Gradle plugin imperatively using the apply script method, which is not possible anymore.\" A similar message names the app_plugin_loader plugin when settings.gradle uses the old method.","The fix touches three files: android\u002Fsettings.gradle gets a pluginManagement and plugins block, android\u002Fbuild.gradle loses its buildscript block, and android\u002Fapp\u002Fbuild.gradle swaps its apply lines for a plugins block.","Firebase projects also move the Google Services and Crashlytics Gradle plugins out of buildscript and into the same plugins blocks.","https:\u002F\u002Fapp369.com\u002Fblog\u002Fflutter-gradle-plugin-applied-imperatively-fix-2026\u002F","Kjdbzu4lCmI6b6y37z8MpsLLi-8i5UN85lDKFD9_Iuw",{"id":2329,"title":2330,"author":2331,"body":2333,"category":470,"createdAt":2911,"description":2912,"disclosure":473,"extension":474,"faq":2913,"howTo":473,"lastVerified":473,"location":494,"meta":2929,"navigation":501,"ogImage":473,"path":2934,"primaryKeyword":2935,"readingTime":504,"related":2936,"seo":2938,"sources":2939,"stem":2956,"tags":2957,"takeaways":2958,"updatedAt":2911,"url":2964,"__hash__":2965},"blog\u002Fblog\u002Fflutter-deleted-android-v1-embedding-build-failed-2026.md","Flutter \"Deleted Android v1 Embedding\" Build Error: The Fix",{"name":7,"social":2332},{"twitter":9},{"type":11,"value":2334,"toc":2902},[2335,2361,2368,2372,2376,2448,2451,2455,2458,2487,2491,2502,2535,2538,2542,2553,2730,2738,2829,2843,2847,2857,2886,2888,2900],[14,2336,2337,2344,2345,2347,2348,1846,2351,2353,2354,1846,2357,2360],{},[17,2338,2339,2340,2343],{},"If ",[22,2341,2342],{},"flutter build"," stops with \"Build failed due to use of deleted Android v1 embedding\", your Android project still uses the wrapper Flutter removed in Flutter 3.29."," For a project that came straight from ",[22,2346,1695],{},", Flutter's guide changes two files: ",[22,2349,2350],{},"MainActivity",[22,2352,439],{},". Custom channel code or a splash screen adds a little more. If the build instead fails inside a plugin with ",[22,2355,2356],{},"cannot find symbol",[22,2358,2359],{},"PluginRegistry.Registrar",", the plugin is the problem, and a newer version of it usually fixes it.",[14,2362,2363,2364,2367],{},"If you landed here from an old link to Flutter's \"Upgrading pre 1.12 Android projects\" wiki page or an old ",[22,2365,2366],{},"flutter.dev\u002Fgo"," migration link, this is what changed and where the steps live now. The facts come from Flutter's breaking-change docs, its migration guide and the Flutter tool's source code, as listed in the sources. I checked each one on October 18, 2026.",[14,2369,2370,1660],{},[17,2371,33],{},[36,2373,2375],{"id":2374},"what-happened-to-the-v1-embedding-and-when","What happened to the v1 embedding, and when",[44,2377,2378,2388],{},[47,2379,2380],{},[50,2381,2382,2384,2386],{},[53,2383,1673],{},[53,2385,1676],{},[53,2387,1679],{},[63,2389,2390,2411,2427],{},[50,2391,2392,2395,2401],{},[68,2393,2394],{},"December 11, 2019",[68,2396,2397,2398,1105],{},"Flutter 1.12 reaches stable with the v2 Android embedding (",[22,2399,2400],{},"io.flutter.embedding",[68,2402,2403,868,2408],{},[131,2404,2407],{"href":2405,"rel":2406},"https:\u002F\u002Fdocs.flutter.dev\u002Frelease\u002Fbreaking-changes\u002Fandroid-v1-embedding-create-deprecation",[135],"Flutter deprecation page",[131,2409,1707],{"href":527,"rel":2410},[135],[50,2412,2413,2416,2422],{},[68,2414,2415],{},"October 1, 2020",[68,2417,2418,2419,2421],{},"Flutter 1.22: ",[22,2420,1695],{}," only makes v2 apps and plugins. Existing v1 apps keep working, but get a migration warning when they use plugins",[68,2423,2424],{},[131,2425,2407],{"href":2405,"rel":2426},[135],[50,2428,2429,2433,2438],{},[68,2430,2431],{},[17,2432,1745],{},[68,2434,2435],{},[17,2436,2437],{},"Flutter 3.29 removes the v1 embedding Java classes",[68,2439,2440,868,2445],{},[131,2441,2444],{"href":2442,"rel":2443},"https:\u002F\u002Fdocs.flutter.dev\u002Frelease\u002Fbreaking-changes\u002Fv1-android-embedding",[135],"Flutter removal page",[131,2446,1707],{"href":527,"rel":2447},[135],[14,2449,2450],{},"Flutter's deprecation page says that by Q2 2020 only 26% of applications used the v1 embedding. In my view, the apps that still hit this error are usually ones created before 2020 and moved to a new Flutter version for the first time in years.",[616,2452,2454],{"id":2453},"what-the-old-addresses-do-today","What the old addresses do today",[14,2456,2457],{},"Checked on October 18, 2026:",[142,2459,2460,2471,2481],{},[145,2461,2462,2463,2466,2467,2470],{},"The ",[17,2464,2465],{},"\"Upgrading pre 1.12 Android projects\""," page on the Flutter GitHub wiki now only says it has moved, and links to the same page in the Flutter repository's ",[22,2468,2469],{},"docs"," folder.",[145,2472,2473,2476,2477,2480],{},[17,2474,2475],{},"flutter.dev\u002Fgo\u002Fandroid-project-migration"," now redirects to Flutter's ",[17,2478,2479],{},"AndroidX migration"," page, which doesn't cover the v1 embedding. The embedding steps are in the repository doc above.",[145,2482,2483,2486],{},[17,2484,2485],{},"flutter.dev\u002Fgo\u002Fandroid-plugin-migration"," redirects to \"Supporting the new Android plugins APIs\", which is still the right page for plugin authors.",[36,2488,2490],{"id":2489},"why-flutter-says-your-app-is-v1","Why Flutter says your app is v1",[14,2492,2493,2494,2497,2498,2501],{},"The check is in the Flutter tool's ",[22,2495,2496],{},"project.dart",". It reads ",[22,2499,2500],{},"android\u002Fapp\u002Fsrc\u002Fmain\u002FAndroidManifest.xml"," and treats the app as v1 when:",[142,2503,2504,2515,2525,2532],{},[145,2505,2506,2507,2510,2511,2514],{},"the ",[22,2508,2509],{},"\u003Capplication>"," tag has ",[22,2512,2513],{},"android:name=\"io.flutter.app.FlutterApplication\"",", or",[145,2516,2517,2518,2521,2522,2514],{},"there is a ",[22,2519,2520],{},"flutterEmbedding"," meta-data tag with value ",[22,2523,2524],{},"1",[145,2526,2527,2528,2531],{},"there is no ",[22,2529,2530],{},"\u003Cmeta-data android:name=\"flutterEmbedding\" android:value=\"2\"\u002F>"," at all, or",[145,2533,2534],{},"the manifest file is missing.",[14,2536,2537],{},"Any of those ends the build with \"Build failed due to use of deleted Android v1 embedding.\" The tool skips this check for add-to-app modules and plugins.",[36,2539,2541],{"id":2540},"fixing-the-app","Fixing the app",[14,2543,2544,2545,2550,2551,424],{},"These are the steps from Flutter's ",[131,2546,2549],{"href":2547,"rel":2548},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002Fmaster\u002Fdocs\u002Fplatforms\u002Fandroid\u002FUpgrading-pre-1.12-Android-projects.md",[135],"Upgrading pre 1.12 Android projects"," guide, for a project made with ",[22,2552,1695],{},[382,2554,2555,2618,2647,2661,2691,2712],{},[145,2556,2557,2562,2563,2566,2567,2570,2571,2574,2575,2578,2579,2582,2583,2604,2607,2608,2611,2612,1846,2615,424],{},[17,2558,2559,2560,424],{},"Update ",[22,2561,2350],{}," Change ",[22,2564,2565],{},"import io.flutter.app.FlutterActivity"," to ",[22,2568,2569],{},"import io.flutter.embedding.android.FlutterActivity"," and delete the ",[22,2572,2573],{},"onCreate"," override that calls ",[22,2576,2577],{},"GeneratedPluginRegistrant.registerWith(this)",". The new ",[22,2580,2581],{},"FlutterActivity"," registers plugins itself.",[1852,2584,2588],{"className":2585,"code":2586,"language":2587,"meta":462,"style":462},"language-kotlin shiki shiki-themes github-light github-dark","import io.flutter.embedding.android.FlutterActivity\n\nclass MainActivity: FlutterActivity()\n","kotlin",[22,2589,2590,2595,2599],{"__ignoreMap":462},[1860,2591,2592],{"class":1862,"line":1863},[1860,2593,2594],{},"import io.flutter.embedding.android.FlutterActivity\n",[1860,2596,2597],{"class":1862,"line":463},[1860,2598,1912],{"emptyLinePlaceholder":501},[1860,2600,2601],{"class":1862,"line":1582},[1860,2602,2603],{},"class MainActivity: FlutterActivity()\n",[2605,2606],"br",{},"If your file is ",[22,2609,2610],{},"MainActivity.java",", the guide's result is the same: ",[22,2613,2614],{},"import io.flutter.embedding.android.FlutterActivity;",[22,2616,2617],{},"public class MainActivity extends FlutterActivity {}",[145,2619,2620,2623,2624,2626,2627,2630,2631,2634,2635,2638,2639,2642,2643,2646],{},[17,2621,2622],{},"Move any platform channel code."," If ",[22,2625,2573],{}," also set up a ",[22,2628,2629],{},"MethodChannel",", move it into a ",[22,2632,2633],{},"configureFlutterEngine(flutterEngine)"," override, and use ",[22,2636,2637],{},"flutterEngine.getDartExecutor().getBinaryMessenger()"," instead of ",[22,2640,2641],{},"getFlutterView()",". The guide's example also calls ",[22,2644,2645],{},"GeneratedPluginRegistrant.registerWith(flutterEngine)"," at the start of that override.",[145,2648,2649,2652,2653,2655,2656,421,2658,424],{},[17,2650,2651],{},"Fix the application tag."," In ",[22,2654,439],{},", replace ",[22,2657,2513],{},[22,2659,2660],{},"android:name=\"${applicationName}\"",[145,2662,2663,2666,2667,947,2669],{},[17,2664,2665],{},"Declare the v2 embedding."," Add this inside ",[22,2668,2509],{},[1852,2670,2674],{"className":2671,"code":2672,"language":2673,"meta":462,"style":462},"language-xml shiki shiki-themes github-light github-dark","\u003Cmeta-data\n    android:name=\"flutterEmbedding\"\n    android:value=\"2\" \u002F>\n","xml",[22,2675,2676,2681,2686],{"__ignoreMap":462},[1860,2677,2678],{"class":1862,"line":1863},[1860,2679,2680],{},"\u003Cmeta-data\n",[1860,2682,2683],{"class":1862,"line":463},[1860,2684,2685],{},"    android:name=\"flutterEmbedding\"\n",[1860,2687,2688],{"class":1862,"line":1582},[1860,2689,2690],{},"    android:value=\"2\" \u002F>\n",[145,2692,2693,2696,2697,2700,2701,2704,2705,393,2708,2711],{},[17,2694,2695],{},"Update the splash screen if you had one."," Remove meta-data named ",[22,2698,2699],{},"io.flutter.app.android.SplashScreenUntilFirstFrame",". The guide shows the replacement: a ",[22,2702,2703],{},"LaunchTheme"," and a ",[22,2706,2707],{},"NormalTheme",[22,2709,2710],{},"styles.xml",", set on the activity.",[145,2713,2714,2717,2718,2721,2722,2725,2726,2729],{},[17,2715,2716],{},"Rebuild."," The guide says the app should then build as normal, for example with ",[22,2719,2720],{},"flutter build apk",". My advice: run ",[22,2723,2724],{},"flutter clean"," first, and ",[22,2727,2728],{},"flutter pub upgrade"," too, because a project this old usually has plugins that are out of date as well.",[14,2731,2732,2733,2737],{},"If your own code uses other removed classes, Flutter's ",[131,2734,2736],{"href":2442,"rel":2735},[135],"removal page"," lists the replacements:",[44,2739,2740,2750],{},[47,2741,2742],{},[50,2743,2744,2747],{},[53,2745,2746],{},"Removed class",[53,2748,2749],{},"Use instead",[63,2751,2752,2764,2776,2790,2802,2814],{},[50,2753,2754,2759],{},[68,2755,2756],{},[22,2757,2758],{},"io.flutter.app.FlutterActivity",[68,2760,2761],{},[22,2762,2763],{},"io.flutter.embedding.android.FlutterActivity",[50,2765,2766,2771],{},[68,2767,2768],{},[22,2769,2770],{},"io.flutter.app.FlutterFragmentActivity",[68,2772,2773],{},[22,2774,2775],{},"io.flutter.embedding.android.FlutterFragmentActivity",[50,2777,2778,2783],{},[68,2779,2780],{},[22,2781,2782],{},"io.flutter.app.FlutterApplication",[68,2784,2785,2786,2789],{},"Removed. Extend ",[22,2787,2788],{},"android.app.Application"," if you need a custom one",[50,2791,2792,2797],{},[68,2793,2794],{},[22,2795,2796],{},"io.flutter.app.FlutterPlayStoreSplitApplication",[68,2798,2799],{},[22,2800,2801],{},"io.flutter.embedding.android.FlutterPlayStoreSplitApplication",[50,2803,2804,2809],{},[68,2805,2806],{},[22,2807,2808],{},"io.flutter.view.FlutterMain",[68,2810,2811],{},[22,2812,2813],{},"io.flutter.embedding.engine.loader.FlutterLoader",[50,2815,2816,2824],{},[68,2817,2818,1846,2821],{},[22,2819,2820],{},"io.flutter.view.FlutterView",[22,2822,2823],{},"FlutterNativeView",[68,2825,2826],{},[22,2827,2828],{},"io.flutter.embedding.android.FlutterView",[14,2830,2831,2832,1846,2835,2838,2839,2842],{},"For add-to-app projects, the same guide has a separate section: remove calls to ",[22,2833,2834],{},"FlutterMain.startInitialization",[22,2836,2837],{},"ensureInitializationComplete",", and replace the ",[22,2840,2841],{},"io.flutter.facade"," classes.",[36,2844,2846],{"id":2845},"fixing-a-plugin-that-still-uses-pluginregistryregistrar","Fixing a plugin that still uses PluginRegistry.Registrar",[14,2848,2849,2850,2853,2854,2856],{},"If the error points at a plugin, its Android code usually still has a ",[22,2851,2852],{},"registerWith(PluginRegistry.Registrar registrar)"," method. That API was removed with the rest of the v1 embedding. When the Flutter tool sees that line in a failed build, it prints its own advice: run ",[22,2855,2728],{}," to get newer plugin versions, and file an issue if that doesn't help.",[142,2858,2859,2872],{},[145,2860,2861,2864,2865,2867,2868,2871],{},[17,2862,2863],{},"If you use the plugin:"," upgrade it, as the tool suggests. My advice: if ",[22,2866,2728],{}," doesn't move it, check pub.dev for a newer major version and run ",[22,2869,2870],{},"flutter pub upgrade --major-versions",". If the plugin has had no release in years, replace it.",[145,2873,2874,2877,2878,2881,2882,2885],{},[17,2875,2876],{},"If you maintain the plugin:"," Flutter's removal page says to delete the ",[22,2879,2880],{},"registerWith"," method from your ",[22,2883,2884],{},"FlutterPlugin"," implementation. The Flutter team did the same for its own plugins in flutter\u002Fpackages#6494.",[36,2887,448],{"id":447},[14,2889,2250,2890,2892,2893,2897,2898,424],{},[131,2891,455],{"href":454}," covers it in two fixed-price steps. A $450 Diagnosis gives you the root cause with evidence and a fixed repair quote within 3 business days, credited toward the fix. If you go ahead, the $1,200 Fix takes 5 business days and comes as a pull request. If the iOS side broke too, see ",[131,2894,2896],{"href":2895},"\u002Fblog\u002Fflutter-ios-build-failed-after-upgrade-2026\u002F","Flutter iOS build failed after an upgrade",", or ",[131,2899,460],{"href":459},[2256,2901,2258],{},{"title":462,"searchDepth":463,"depth":463,"links":2903},[2904,2907,2908,2909,2910],{"id":2374,"depth":463,"text":2375,"children":2905},[2906],{"id":2453,"depth":1582,"text":2454},{"id":2489,"depth":463,"text":2490},{"id":2540,"depth":463,"text":2541},{"id":2845,"depth":463,"text":2846},{"id":447,"depth":463,"text":448},"2026-10-18T21:00:00.000Z","Flutter removed the Android v1 embedding in Flutter 3.29 (February 12, 2025), so older projects now stop with \"Build failed due to use of deleted Android v1 embedding\" or a plugin error about PluginRegistry.Registrar. What the error means, how Flutter decides your app is v1, and the exact AndroidManifest and MainActivity changes, from Flutter's docs and source checked October 18, 2026.",[2914,2917,2920,2923,2926],{"question":2915,"answer":2916},"What does \"Build failed due to use of deleted Android v1 embedding\" mean?","The Flutter tool decided your Android app still uses the old v1 embedding, which was removed in Flutter 3.29. In Flutter's source, that happens when AndroidManifest.xml uses io.flutter.app.FlutterApplication, or has no flutterEmbedding meta-data with value 2, or the AndroidManifest.xml file is missing.",{"question":2918,"answer":2919},"How do I fix the deleted Android v1 embedding error?","Follow Flutter's \"Upgrading pre 1.12 Android projects\" steps: import io.flutter.embedding.android.FlutterActivity in MainActivity, remove the old onCreate plugin registration, set android:name=\"${applicationName}\" on the application tag, and add \u003Cmeta-data android:name=\"flutterEmbedding\" android:value=\"2\"\u002F> inside \u003Capplication>.",{"question":2921,"answer":2922},"Which Flutter version removed the v1 embedding?","Flutter 3.29. Flutter's breaking-change page says the removal landed in 3.28.0-0.1.pre and shipped in stable 3.29, which Flutter's release archive dates February 12, 2025.",{"question":2924,"answer":2925},"Why does a plugin fail with \"cannot find symbol\" PluginRegistry.Registrar?","The plugin usually still has a registerWith method that takes a PluginRegistry.Registrar, a v1 API removed in Flutter 3.29. Flutter's build output suggests running flutter pub upgrade to get a newer plugin version. If no fixed version exists, the method has to be removed from the plugin.",{"question":2927,"answer":2928},"Can I keep using the v1 embedding on an older Flutter version?","Flutter's breaking-change page says it was removed in 3.29, so earlier versions still have it. In my view, pinning an old Flutter only delays the fix. Newer plugin versions and store requirements move on, and for a standard flutter create project the migration changes two files.",{"readingTimeStats":2930},{"text":497,"minutes":2931,"time":2932,"words":2933},4.1,246000,820,"\u002Fblog\u002Fflutter-deleted-android-v1-embedding-build-failed-2026","build failed due to use of deleted android v1 embedding",[2301,2300,2937],"how-to-debug-a-flutter-firebase-bug-2026",{"title":2330,"description":2912},[2940,2942,2944,2946,2949,2952,2955],{"title":2941,"url":2442},"Flutter docs, Removal of v1 Android embedding Java APIs (last updated July 31, 2026)",{"title":2943,"url":2405},"Flutter docs, Android v1 embedding app and plugin creation deprecation",{"title":2945,"url":2547},"Flutter on GitHub, Upgrading pre 1.12 Android projects",{"title":2947,"url":2948},"Flutter docs, Supporting the new Android plugins APIs","https:\u002F\u002Fdocs.flutter.dev\u002Frelease\u002Fbreaking-changes\u002Fplugin-api-migration",{"title":2950,"url":2951},"Flutter on GitHub, flutter_tools project.dart (embedding check)","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002Fmaster\u002Fpackages\u002Fflutter_tools\u002Flib\u002Fsrc\u002Fproject.dart",{"title":2953,"url":2954},"Flutter on GitHub, flutter_tools gradle_errors.dart (v1 embedding plugin handler)","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002Fmaster\u002Fpackages\u002Fflutter_tools\u002Flib\u002Fsrc\u002Fandroid\u002Fgradle_errors.dart",{"title":526,"url":527},"blog\u002Fflutter-deleted-android-v1-embedding-build-failed-2026","build failed due to use of deleted android v1 embedding, flutter v1 embedding, flutter v2 embedding migration, flutterEmbedding meta-data, io.flutter.app.FlutterActivity, PluginRegistry.Registrar cannot find symbol, registerWith registrar flutter plugin, flutter 3.29 android build error, upgrading pre 1.12 android projects",[2959,2960,2961,2962,2963],"Flutter removed the Android v1 embedding in Flutter 3.29, released on February 12, 2025. Classes such as io.flutter.app.FlutterActivity, io.flutter.app.FlutterApplication and io.flutter.view.FlutterView no longer exist.","The Flutter tool treats an app as v1, and stops with \"Build failed due to use of deleted Android v1 embedding\", when its AndroidManifest.xml uses io.flutter.app.FlutterApplication or lacks \u003Cmeta-data android:name=\"flutterEmbedding\" android:value=\"2\"\u002F>.","The app fix is Flutter's own migration: change the FlutterActivity import, move custom channel setup into configureFlutterEngine, set android:name=\"${applicationName}\" and add the flutterEmbedding meta-data with value 2.","A plugin that still has a registerWith(PluginRegistry.Registrar) method fails to compile instead. Flutter's build output suggests flutter pub upgrade, and plugin authors should delete registerWith.","The v2 embedding arrived in Flutter 1.12 in December 2019, and flutter create stopped making v1 projects in Flutter 1.22, so, in my view, the apps hit now are mostly ones created before 2020 and not updated since.","https:\u002F\u002Fapp369.com\u002Fblog\u002Fflutter-deleted-android-v1-embedding-build-failed-2026\u002F","XCzq_ukIlixYX4apwJmjPfdlWXhqHCbmPMl9c9Hexls",[2967,2969,2972,2975,2976,2979],{"keyword":5,"url":536,"title":5,"relevance":2968},70,{"keyword":2970,"url":2971,"title":2970,"relevance":1944},"Google Play Requires Target API 36: The Android 16 Update","https:\u002F\u002Fapp369.com\u002Fblog\u002Fgoogle-play-target-api-36-android-16-requirement-2026\u002F",{"keyword":2973,"url":2974,"title":2973,"relevance":1938},"Google Sign-In for Android Is Deprecated: Moving to Credential Manager","https:\u002F\u002Fapp369.com\u002Fblog\u002Fgoogle-sign-in-android-deprecated-credential-manager-2026\u002F",{"keyword":2330,"url":2964,"title":2330,"relevance":1915},{"keyword":2977,"url":2978,"title":2977,"relevance":1915},"Google Fit API Deprecated: Moving to Health Connect in 2026","https:\u002F\u002Fapp369.com\u002Fblog\u002Fgoogle-fit-api-deprecated-health-connect-2026\u002F",{"keyword":2980,"url":2981,"title":2980,"relevance":1915},"JCenter Shutdown: Fixing Old Android and Flutter Builds","https:\u002F\u002Fapp369.com\u002Fblog\u002Fjcenter-bintray-shut-down-fix-android-flutter-builds-2026\u002F",1792347285491]