Migrate from Firebase App Distribution
This guide shows how to replace a Firebase App Distribution (FAD) upload step with buildtree. You can keep your existing build commands and use buildtree for install links, branch organisation and tester access.
buildtree replaces the distribution piece directly. Builds keep being built the way you build them; only the upload step changes. This guide assumes you have a FAD project with one or more apps and a CI pipeline that calls the FAD CLI, Fastlane plugin, or Gradle plugin.
What you keep, what you replace
| FAD feature | buildtree equivalent |
|---|---|
| App (one per platform) | Project (cross-platform; iOS + Android live in the same project) |
| Tester groups | Allowlist + Private mode (see Install access) |
| Public link via Firebase Hosting | Public install URL on every build |
firebase appdistribution:distribute | buildtree upload |
firebase_app_distribution Fastlane action | buildtree upload |
Gradle appDistributionUpload task | buildtree upload |
| Release notes | Build metadata (auto-extracted from IPA/APK) + release tags |
| Group / tester management | Allowlist editor in the project dashboard |
| Build categories (none) | Branch + environment + release tag |
| iOS UDID via Apple Dev portal manually | Built-in UDID registration flow (see iOS distribution) |
Replace the upload step
-
Install the CLI and authenticate:
npm install -g @buildtree/cli buildtree login -
Replace your FAD upload step. In your CI workflow, swap the FAD invocation for:
buildtree upload ./app.apk --env prodThe first time you run this interactively the CLI prompts you to create a project and pick a slug; that slug becomes part of your install URLs and is reused on every subsequent upload. For preview builds tied to a feature branch:
buildtree upload ./app.apk --env dev --branch feature/paymentsThat is the only line that changes. Your build commands stay the same.
-
Share the install URL with your QA team. The dashboard shows three URL types:
- Pinned: a specific build, available while that build is retained.
- Folder: always-latest for a given
(env, branch)pair. - Release: frozen to a release tag.
Share the folder URL when testers should receive the latest upload. Use a pinned URL when they need to review a specific build.
CI integration
Firebase CLI
If your CI runs firebase appdistribution:distribute today:
firebase appdistribution:distribute ./app.apk \
--app 1:1234567890:android:abcdef \
--groups internal-testers \
--release-notes "Build $GITHUB_SHA"
Replace with:
buildtree upload ./app.apk --env prod
No app ID needed (the binary's bundle ID is read from the file). No --groups flag (testers are controlled by the project's allowlist on the dashboard, which doesn't change per build). Release notes map to a release tag with --release v1.5.0 if you want a frozen install URL per version.
Fastlane
Replace the firebase_app_distribution action with a shell call:
lane :distribute do
sh "buildtree upload ../app.ipa --env prod"
end
Pass the API token via the BUILDTREE_TOKEN environment variable on the runner.
Gradle
Drop the com.google.firebase.appdistribution plugin and its config block. Add a single Gradle task or invoke the CLI directly in your CI step after assembleRelease:
./gradlew assembleRelease
buildtree upload ./app/build/outputs/apk/release/app-release.apk --env prod
GitHub Actions
Generate an API token from the dashboard's Settings → API Tokens page and add it as a GitHub repository secret called BUILDTREE_TOKEN. Then:
- name: Distribute to buildtree
env:
BUILDTREE_TOKEN: ${{ secrets.BUILDTREE_TOKEN }}
run: |
npm install -g @buildtree/cli
buildtree upload ./build/app.apk --env prod
Full example workflows for iOS and Android: see GitHub Actions.
Tester onboarding
FAD requires testers to either install the Firebase App Tester app (Android) or accept an invitation tied to a Google account. buildtree replaces this with a one-line shareable URL:
- Public projects: anyone with the URL can install. No tester signup, no Google account, no email gate.
- Private projects (Solo and above): testers verify their email once via a magic link. They never sign up for an account or download anything. See Install access.
Send external testers, contractors and clients the install URL. For private projects, add their email addresses to the allowlist first.
iOS UDID handling
FAD documents asking testers to register their UDID separately, then you paste it into the Apple Developer portal manually before re-uploading the build. buildtree builds the UDID flow into the platform:
- Share the project's public registration URL with iOS testers.
- They open it on the device they want to install on, fill in name and email.
- iOS prompts them to install a profile; the device's UDID lands in your dashboard.
- You approve each request from the Devices page.
- One click exports approved UDIDs in Apple Dev Portal format (the tab-separated
UDID<TAB>Nameformat the bulk-add tool expects). - Re-build your IPA with the new provisioning profile and upload.
See iOS distribution for provisioning requirements and the full registration flow.
Release notes
FAD stores a freeform --release-notes string per build. buildtree extracts version, build number, bundle ID, and display name from the IPA or APK at upload time, so the "what changed" facts are surfaced without you typing them.
For human-readable changelogs, the closest equivalent is a release tag:
buildtree upload ./app.ipa --env prod --release v1.5.0
The release URL is frozen and shareable. Pair it with the changelog entry in your repo, in Slack, or in the PR description. A native release-notes field is on the roadmap.
What does not transfer automatically
- Tester groups: there is no programmatic import of FAD tester rosters today. Export the email list from the FAD console and paste it into the buildtree allowlist as a multiline block (one email per line, or
*@yourcompany.comfor whole-team coverage). - Historical builds: FAD storage stays where it is until you delete the Firebase project. If you want to preserve specific release URLs on buildtree, re-upload the IPA or APK with
buildtree upload --release <tag>. - Crashlytics / Analytics: these are separate Firebase products. They keep working with FAD removed; nothing in your app code changes. buildtree does not replace them.
Common questions
Do I need to change my build pipeline? No. buildtree replaces the upload step only. Local Xcode builds, Fastlane lanes, EAS local builds, native Gradle, and CI builds on any provider all produce a file, and buildtree upload takes it from there.
Can I keep Crashlytics? Yes. Crashlytics and FAD are unrelated products under the Firebase umbrella. Removing the FAD plugin or Fastlane action does not affect the Crashlytics SDK in your app.
Is the QA install link the same URL each release? Yes if you share the folder URL (/install/folder/<project>/<env> or /install/folder/<project>/<env>/<branch>). It always points to the latest build for that environment. The link continues to work while matching builds are available.
What does buildtree cost? The Free plan includes 1 project, 5 GB of storage and 30-day build retention. Paid plans add capacity and private install links.
Need help
If you are migrating a larger team and want help mapping FAD tester groups to buildtree allowlists, email hello@buildtree.sh.
Last updated