This guide is for developers who fork this repo and want to run it against their own Firebase project.
It is written for someone starting from zero. If you have never created a Firebase project, never downloaded google-services.json, and never wired a .NET MAUI app to Firebase before, follow this guide in order.
- creating your own Firebase project
- registering the Android app in Firebase
- downloading your own
google-services.json - placing the file where this repo expects it
- enabling the Firebase features this repo uses
- building the app with the local
build.ps1script - avoiding the most common setup mistakes
- Firebase Android setup:
https://firebase.google.com/docs/android/setup - Firebase project setup:
https://firebase.google.com/docs/projects/learn-more - Firebase Google Sign-In for Android:
https://firebase.google.com/docs/auth/android/google-signin - Firebase Realtime Database:
https://firebase.google.com/docs/database - Firebase Authentication:
https://firebase.google.com/docs/auth
- .NET MAUI single-project overview:
https://learn.microsoft.com/dotnet/maui/fundamentals/single-project?view=net-maui-10.0 - .NET MAUI project configuration:
https://learn.microsoft.com/dotnet/maui/deployment/visual-studio-properties?view=net-maui-10.0
To make the examples copy/paste safe, this guide uses these path conventions:
- Repository root means the folder that contains
build.ps1,README.md,docs/, and theEpubReader/project folder. - In your clone, that will look like:
C:\Users\james\source\repos\EpubReader
- Unless a step says otherwise, run all PowerShell commands from the repository root.
Before running the script examples, change into your clone root:
Set-Location "C:\path\to\your\EpubReader-clone"Then commands such as these work as written:
./build.ps1 -Android -DebugBuild
Copy-Item "build-secrets\google-services.json" "EpubReader\Resources\Raw\google-services.json" -ForceIf you are not in the repository root, use the script's full path instead:
pwsh -File "C:\path\to\your\EpubReader-clone\build.ps1" -Android -DebugBuildbuild.ps1 resolves repo-relative paths from the script location, so pwsh -File <full-path-to-build.ps1> is the safest option when you are unsure of your current directory.
Before you create anything in Firebase, understand these repo-specific facts:
- The .NET MAUI app project is
EpubReader/EpubReader.csproj. - The current app ID is defined in that project file with
ApplicationId. - The current default Android app ID is
com.companyname.epubreader. - Android builds use
google-services.json. - The local build script is
build.ps1in the repository root. - The Android target in
EpubReader/EpubReader.csprojincludes this item:
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">
<GoogleServicesJson Include="Resources\Raw\google-services.json" />
</ItemGroup>- That means direct Android builds from Visual Studio, Visual Studio Code, or
dotnet buildexpect a real file atEpubReader/Resources/Raw/google-services.json. - The build script looks for
google-services.jsonin these locations:build-secrets/google-services.jsonbuild-secrets/android/google-services.jsonEpubReader/build-secrets/google-services.jsonEpubReader/build-secrets/android/google-services.json
This leads to two supported workflows:
- Build script workflow
- keep your secret file in
build-secrets/... - run
./build.ps1 - the script stages the file into
EpubReader/Resources/Raw/google-services.jsonfor the build
- keep your secret file in
- Direct IDE workflow
- place your real file directly at
EpubReader/Resources/Raw/google-services.json - then use Visual Studio, Visual Studio Code, or direct
dotnet build
- place your real file directly at
For a first successful build, the easiest path is:
- keep the existing app ID
- create a Firebase Android app for that exact app ID
- download
google-services.json - put it in
build-secrets/google-services.json - run
./build.ps1 -Android -DebugBuild
If you change the app ID later, you must register a matching app in Firebase and download a new google-services.json.
- Fork the repository in GitHub.
- Clone your fork locally.
- Open the solution in Visual Studio 2026 with the .NET MAUI workload installed.
- Confirm that
EpubReader/EpubReader.csprojloads correctly.
Use this if you just want to get the app running quickly.
Current value in this repo:
com.companyname.epubreader
If you choose this option:
- do not change
ApplicationIdyet - create the Android app in Firebase with exactly
com.companyname.epubreader
Use this if you want your fork to have its own identity.
Typical format:
com.yourname.epubreadercom.yourcompany.epubreadercom.yourorg.bookreader
If you choose this option, update EpubReader/EpubReader.csproj first:
<ApplicationId>com.yourcompany.epubreader</ApplicationId>In .NET MAUI single-project apps, the app ID is configured in the project file. Microsoft Learn documents this under the .NET MAUI project configuration and single-project model.
Important:
- the Firebase Android app package name must match the app ID exactly
- if they do not match, Google sign-in will fail
This repo's Android Debug and Release builds also depend on the Android signing properties in EpubReader/EpubReader.csproj.
At the time of writing, the project contains Android-specific signing blocks for both:
Release|net10.0-android|AnyCPUDebug|net10.0-android|AnyCPU
Those property groups point to:
AndroidSigningKeyStoreAndroidSigningStorePassAndroidSigningKeyAliasAndroidSigningKeyPass
If those values are wrong for your machine, Android builds can fail before the app runs.
AndroidSigningKeyStore is resolved relative to EpubReader/EpubReader.csproj, not relative to the repository root.
So these are different:
Epubreader.keystore- means a file next to
EpubReader.csproj
- means a file next to
..\build-secrets\android\MyFork.keystore- means a file under
build-secrets/android/at the repository root
- means a file under
If the existing repo keystore works for your local build, you can leave these properties unchanged.
If you want to use your own signing file, update both Android property groups in EpubReader/EpubReader.csproj so that Debug and Release are consistent.
Example shape:
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net10.0-android|AnyCPU'">
<AndroidPackageFormat>apk</AndroidPackageFormat>
<AndroidKeyStore>True</AndroidKeyStore>
<AndroidUseAapt2>True</AndroidUseAapt2>
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
<AndroidSigningKeyStore>..\build-secrets\android\MyFork.keystore</AndroidSigningKeyStore>
<AndroidSigningStorePass>your-store-password</AndroidSigningStorePass>
<AndroidSigningKeyAlias>your-key-alias</AndroidSigningKeyAlias>
<AndroidSigningKeyPass>your-key-password</AndroidSigningKeyPass>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net10.0-android|AnyCPU'">
<AndroidUseAapt2>True</AndroidUseAapt2>
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi>
<AndroidPackageFormat>apk</AndroidPackageFormat>
<AndroidKeyStore>True</AndroidKeyStore>
<AndroidSigningKeyStore>..\build-secrets\android\MyFork.keystore</AndroidSigningKeyStore>
<AndroidSigningStorePass>your-store-password</AndroidSigningStorePass>
<AndroidSigningKeyAlias>your-key-alias</AndroidSigningKeyAlias>
<AndroidSigningKeyPass>your-key-password</AndroidSigningKeyPass>
</PropertyGroup>Update the Android signing values if:
- your fork uses a different keystore file
- the keystore file is stored in a different folder
- the alias or passwords are different on your machine
- Android build fails with signing or keystore errors
To keep custom signing files out of source control, a practical local layout is:
build-secrets/android/MyFork.keystore
Then set:
AndroidSigningKeyStoreto..\build-secrets\android\MyFork.keystore
Because that path is relative to EpubReader/EpubReader.csproj.
From the repository root, test the Android build again:
./build.ps1 -Android -DebugBuildor, from any directory:
pwsh -File "C:\path\to\your\EpubReader-clone\build.ps1" -Android -DebugBuild- Go to the Firebase Console:
https://console.firebase.google.com/
- Select Create a project.
- Enter a project name.
- Example:
EpubReader-MyFork
- Example:
- Choose whether to enable Google Analytics.
- For local development, this is optional.
- Finish creating the project.
After the project is created, you will be on the Firebase project dashboard.
- In your Firebase project, click Add app.
- Choose Android.
- Enter the Android package name.
- If you kept the default repo value, use
com.companyname.epubreader. - If you changed
ApplicationId, use your new exact value.
- If you kept the default repo value, use
- Enter an app nickname if you want.
- Example:
EpubReader Android Dev
- Example:
- Enter your debug SHA-1 certificate fingerprint.
- This is strongly recommended for Google Sign-In.
Open PowerShell and run:
keytool -list -v -keystore "$env:USERPROFILE\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass androidLook for:
SHA1:
Copy that SHA-1 value and paste it into Firebase when registering the Android app.
If keytool is not found:
- install the Android / Java tooling that comes with the MAUI and Android workload in Visual Studio
- or run the command from a developer shell where Java is on
PATH
- Click Register app.
After registering the Android app, Firebase offers a configuration file download.
- Click Download
google-services.json. - Save it somewhere temporary, such as your Downloads folder.
- Do not reuse the file from this repo for your fork.
- Do not rename it.
The filename must stay exactly:
google-services.json
Before placing the file in the repo, verify it belongs to your Firebase project and your app ID.
In PowerShell:
$json = Get-Content "$env:USERPROFILE\Downloads\google-services.json" -Raw | ConvertFrom-Json
$json.project_info.project_id
$json.client[0].client_info.android_client_info.package_name
$json.client[0].oauth_client | Select-Object client_type, client_idWhat to check:
project_idis your Firebase projectpackage_namematches your.NET MAUIApplicationId- there is an OAuth client with
client_type3- this is the web client ID used by Google sign-in
If package_name does not match your app ID, stop and register the app again in Firebase with the correct package name.
Recommended location for the build.ps1 workflow:
build-secrets/google-services.json
Create the folder if needed:
New-Item -ItemType Directory -Path "build-secrets" -Force
Copy-Item "$env:USERPROFILE\Downloads\google-services.json" "build-secrets\google-services.json" -ForceYou can also use:
build-secrets/android/google-services.json
The repo build script will detect either location.
Because the Android target includes GoogleServicesJson Include="Resources\Raw\google-services.json", direct Android builds expect the file to exist inside the project at:
EpubReader/Resources/Raw/google-services.json
If you want to build or debug without build.ps1, copy the file there:
Copy-Item "build-secrets\google-services.json" "EpubReader\Resources\Raw\google-services.json" -ForceUse this direct-project copy when you want to:
- press F5 in Visual Studio
- press F5 in Visual Studio Code
- run
dotnet buildmanually - use other IDE tasks that do not call
build.ps1
Important:
- keep this file local
- do not commit your personal Firebase config to your fork unless you intentionally want it public
- always check
git statusbefore committing
This repo uses Google sign-in on Android.
In Firebase Console:
- Open Authentication.
- Open Sign-in method.
- Enable Google.
- Choose or verify the project support email.
- Save.
If Google provider is disabled, the login flow will start but Firebase sign-in will fail.
This repo also uses Firebase Realtime Database for sync.
In Firebase Console:
- Open Build → Realtime Database.
- Click Create Database.
- Choose a region.
- Choose your starting security mode.
For early local development, many developers start with test mode temporarily and then tighten rules.
After the database is created, verify that your downloaded google-services.json has a firebase_url entry.
You can check with:
$json = Get-Content "build-secrets\google-services.json" -Raw | ConvertFrom-Json
$json.project_info.firebase_urlFrom the repository root, run one of these commands.
./build.ps1 -Android -DebugBuildRun that command from the repository root.
./build.ps1 -Android -DebugBuild -GoogleJsonPath "./build-secrets/google-services.json"That relative ./build-secrets/... path assumes you are running the command from the repository root.
./build.ps1 -Android -DebugBuild -ApiKey "your-api-key" -AuthDomain "your-project.firebaseapp.com" -DatabaseUrl "https://your-project-default-rtdb.firebaseio.com"If you want to run the script from another directory, prefer:
pwsh -File "C:\path\to\your\EpubReader-clone\build.ps1" -Android -DebugBuildWhat the build script does:
- sets Firebase environment variables for the build process
- looks for your
google-services.json - stages it into the Android resource location when needed
- builds
EpubReader/EpubReader.csproj
If you use an IDE instead of build.ps1, make sure your Firebase file is in the project first:
EpubReader/Resources/Raw/google-services.json
This repo's FirebaseConfig currently reads Firebase settings from the packaged google-services.json file at runtime.
That means the Windows app also needs the file packaged into the app, which is why for Windows builds you should copy your file to:
EpubReader/Resources/Raw/google-services.json
Do not assume that passing only -ApiKey, -AuthDomain, or -DatabaseUrl is enough for the Windows app today. For the current codebase, the safest Windows setup is to provide a real google-services.json file in Resources/Raw before building or running.
If you want to run the Windows version of the app with your own Firebase project:
- Copy your Firebase file into the project:
Copy-Item "build-secrets\google-services.json" "EpubReader\Resources\Raw\google-services.json" -ForceRun that command from the repository root.
- Build or run the Windows target.
Examples:
./build.ps1 -Windows -DebugBuild
dotnet build EpubReader/EpubReader.csproj -f net10.0-windows10.0.19041.0Run both commands from the repository root.
- Launch the Windows app from Visual Studio, Visual Studio Code, or your existing Windows run task/script.
Microsoft Learn documents that .NET MAUI Android apps can be run from Visual Studio by choosing an Android emulator in the debug target and starting the app.
- Open the repo in Visual Studio 2026.
- Confirm the
.NET MAUIworkload is installed. - Confirm your Firebase file exists at:
EpubReader/Resources/Raw/google-services.json
- In Solution Explorer, select the
EpubReaderproject. - In the Visual Studio toolbar, choose an Android emulator or connected device as the debug target.
- Press F5 or click Start.
If Visual Studio prompts you to install missing Android components, let it complete that setup first. Microsoft Learn documents this emulator and SDK flow in the .NET MAUI first-app guidance.
- Open the repo in Visual Studio 2026.
- Confirm your Firebase file exists at:
EpubReader/Resources/Raw/google-services.json
- In the Visual Studio toolbar, choose Windows Machine as the debug target.
- Press F5 or click Start.
If the app starts but fails during Firebase initialization, re-check that google-services.json was copied into EpubReader/Resources/Raw before the build.
Microsoft Learn documents that .NET MAUI projects in Visual Studio Code use the .NET MAUI extension, the .NET MAUI: Configure Android command, and an Android debug target selected from the status bar.
- Install the
.NET MAUIextension in Visual Studio Code. - Open the repo folder.
- Press
Ctrl+Shift+Pand run:.NET MAUI: Configure Android- then
Refresh Android environment
- Confirm your Firebase file exists at:
EpubReader/Resources/Raw/google-services.json
- In the status bar, choose an Android emulator or connected device as the debug target.
- Press F5 or use the Run button.
If Visual Studio Code reports missing Android SDK or JDK components, use the official .NET MAUI: Configure Android flow to install or point to them before trying again.
- Open the repo folder in Visual Studio Code.
- Confirm your Firebase file exists at:
EpubReader/Resources/Raw/google-services.json
- In the status bar, choose Windows as the debug target.
- Press F5 or use the Run button.
If you use a VS Code task or manual CLI command for Windows, copy the Firebase file into EpubReader/Resources/Raw first so it is packaged with the app.
After the app launches on Android:
- navigate to the login screen
- tap Google sign-in
- choose a Google account
- confirm sign-in completes
- read a book and verify the app continues working
If sign-in fails, check the troubleshooting section below.
If you want your fork to use a custom app ID, keep these aligned:
EpubReader/EpubReader.csproj<ApplicationId>
- Firebase Android app registration
- Android package name
- downloaded
google-services.jsonclient[0].client_info.android_client_info.package_name
When you change the app ID:
- update
ApplicationId - register a new Android app in Firebase with the new package name
- download a new
google-services.json - replace your local file in
build-secrets - rebuild
Be aware of the current repo state:
- Android Google sign-in is wired
AuthenticationService.macios.cscurrently blocks Google sign-in until native iOS / Mac Catalyst provider configuration is completed
If you only want a successful first-time setup for your fork, start with Android.
If you later want iOS support, you will also need:
- an iOS app registered in Firebase
- a
GoogleService-Info.plist - Apple signing / provisioning configured for your bundle ID
- native iOS Google sign-in configuration completed in the app
Check:
- the file name is exactly
google-services.json - the file is in
build-secrets/google-services.jsonor another supported build-secrets path - you are running
build.ps1from the repository root
Check:
ApplicationIdinEpubReader/EpubReader.csprojpackage_nameinsidegoogle-services.json- the Android app registration in Firebase
All three must match.
This usually means OAuth / SHA-1 configuration is wrong.
Check:
- Google provider is enabled in Firebase Authentication
- your debug SHA-1 fingerprint is added to the Firebase Android app
- you downloaded a fresh
google-services.jsonafter updating fingerprints - the app package name in Firebase matches the app package name in your MAUI project
If you changed the signing key or package name, re-download google-services.json.
This repo reads the web OAuth client from google-services.json.
Check:
$json = Get-Content "build-secrets\google-services.json" -Raw | ConvertFrom-Json
$json.client[0].oauth_client | Format-Table client_type, client_idYou should see a client with client_type equal to 3.
Check:
- the JSON file is valid
- the file belongs to your Firebase project
- the build used the correct file
FIREBASE_API_KEY,FIREBASE_AUTH_DOMAIN, andFIREBASE_DATABASE_URLare present if you are building from explicit parameters or environment variables
Check:
- Realtime Database was created in your Firebase project
- the URL in
google-services.jsonis correct - your database rules allow the scenario you are testing
- the user is authenticated if your rules require authentication
Use this checklist if you want the shortest path to success:
- fork the repo
- keep
ApplicationIdascom.companyname.epubreader - create a Firebase project
- register an Android app with package name
com.companyname.epubreader - add the debug SHA-1 fingerprint
- in PowerShell, run
keytool -list -v -keystore "$env:USERPROFILE\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android - copy the value shown next to
SHA1: - in Firebase Console, open your Android app settings and add that fingerprint if you did not enter it during app registration
- in PowerShell, run
- enable Google sign-in in Firebase Authentication
- create Realtime Database
- download
google-services.json - copy it to
build-secrets/google-services.json - run
./build.ps1 -Android -DebugBuild - launch the app and test Google sign-in
Once your local fork works, consider these next steps:
- change
ApplicationTitleandApplicationIdfor your fork - register a new Firebase Android app for the new package name
- download a new
google-services.json - create separate Firebase projects for development and production
- review and tighten Realtime Database security rules
- verify you are not committing secrets before pushing changes