|
| 1 | +This document provides a detailed guide for AI agents to understand and contribute to the Firebase Admin .NET SDK. Adhering to these guidelines is crucial for maintaining code quality, consistency, and idiomatic C# practices. |
| 2 | + |
| 3 | +## High-Level Overview |
| 4 | + |
| 5 | +The Firebase Admin .NET SDK provides C# developers with access to Firebase services on privileged environments. Its design emphasizes idiomatic C#, thread-safety, and a consistent, predictable API surface. |
| 6 | + |
| 7 | +## Directory Structure |
| 8 | + |
| 9 | +- **`FirebaseAdmin/FirebaseAdmin.sln`**: The main solution file for the entire project. |
| 10 | +- **`FirebaseAdmin/FirebaseAdmin/`**: The primary source code for the SDK. |
| 11 | + - **`FirebaseAdmin/FirebaseAdmin/FirebaseApp.cs`**: The main entry point and initialization class for the SDK. |
| 12 | + - **`FirebaseAdmin/FirebaseAdmin/Auth/`**: Source code for the Authentication service. |
| 13 | + - **`FirebaseAdmin/FirebaseAdmin/Messaging/`**: Source code for the Firebase Cloud Messaging (FCM) service. |
| 14 | + - **`FirebaseAdmin/FirebaseAdmin/Util/`**: Internal helper utilities and classes used across services (e.g. Wrapping low level http exceptions as a `FirebaseException`). |
| 15 | +- **`FirebaseAdmin/FirebaseAdmin.Tests/`**: Unit tests for the SDK. |
| 16 | +- **`FirebaseAdmin/FirebaseAdmin.IntegrationTests/`**: Integration tests. |
| 17 | +- **`FirebaseAdmin/FirebaseAdmin.Snippets/`**: Code snippets used in documentation. |
| 18 | + |
| 19 | +## Core Design Patterns |
| 20 | + |
| 21 | +- **Initialization**: The SDK is initialized via the `FirebaseApp.Create()` method, which configures a singleton instance. |
| 22 | +- **Service Clients**: Services like `FirebaseAuth` and `FirebaseMessaging` are accessed through the `FirebaseApp.DefaultInstance`. |
| 23 | +- **Error Handling**: Exceptions are the primary mechanism for error handling. Custom exceptions inherit from `FirebaseException` (defined in `FirebaseAdmin/FirebaseAdmin/FirebaseException.cs`) and are defined within each service module. |
| 24 | +- **HTTP Communication**: All outgoing HTTP requests are managed by a centralized `HttpClient` provided via the `AppOptions.HttpClientFactory`. |
| 25 | +- **Asynchronous Operations**: Asynchronous operations are handled using `Task`-based asynchronous programming (`async`/`await`). |
| 26 | + |
| 27 | +## Coding Style and Naming Conventions |
| 28 | + |
| 29 | +- **Formatting**: Code style is enforced using `stylecop`. Run `dotnet format` to apply the rules. |
| 30 | +- **Naming**: |
| 31 | + - Constants, classes and public methods use `PascalCase`. |
| 32 | + - Private members are not explicitly prefixed. |
| 33 | + |
| 34 | +## Testing Philosophy |
| 35 | + |
| 36 | +- **Unit Tests**: Located in `FirebaseAdmin.Tests/`, with a file naming pattern of `*Test.cs`. `xunit` is the testing framework. |
| 37 | +- **Integration Tests**: Located in `FirebaseAdmin.IntegrationTests/`. These tests interact with live Firebase services and require a configured service account. |
| 38 | + |
| 39 | +### How to Run Tests |
| 40 | + |
| 41 | +The unit tests can be run using the `dotnet test` command. Ensure that the required .NET frameworks (net462 and net6.0) are installed in your environment. |
| 42 | + |
| 43 | +To run the tests for a specific framework, use the `--framework` flag: |
| 44 | +```bash |
| 45 | +# Run tests for .NET 6.0 |
| 46 | +dotnet test FirebaseAdmin/FirebaseAdmin.Tests --framework net6.0 |
| 47 | + |
| 48 | +# Run tests for .NET 4.6.2 |
| 49 | +dotnet test FirebaseAdmin/FirebaseAdmin.Tests --framework net462 |
| 50 | +``` |
| 51 | + |
| 52 | +**Note on Integration Tests:** The integration tests require a configured service account and other setup that is not available in all environments. It is recommended to rely on the CI for running integration tests. |
| 53 | + |
| 54 | + |
| 55 | +## Dependency Management |
| 56 | + |
| 57 | +- **Manager**: Dependencies are managed using NuGet. |
| 58 | +- **Manifest**: The `FirebaseAdmin/FirebaseAdmin/FirebaseAdmin.csproj` file lists all dependencies. |
| 59 | +- **Command**: To add a dependency, use `dotnet add package <PACKAGE_NAME>`. |
| 60 | + |
| 61 | +## Critical Developer Journeys |
| 62 | + |
| 63 | +### Journey 1: How to Add/Update a New API Method |
| 64 | + |
| 65 | +1. **Public Method**: Define the new public method or changes in the relevant service class (e.g., `FirebaseAuth.cs`). |
| 66 | +2. **Internal Logic**: Implement the core logic as a private method. |
| 67 | +3. **HTTP Client**: Use the existing HTTP Client implementation for that service to make the API call. |
| 68 | +4. **Error Handling**: Wrap API calls in `try-catch` blocks and throw appropriate `FirebaseException` subtypes. |
| 69 | +5. **Testing**: Add a unit test in the corresponding `*Test.cs` file and an integration test in `FirebaseAdmin.IntegrationTests/` where appropriate. This should be thorough and update any tests where the new changes would affect. |
| 70 | +6. **Snippet**: Add or update code snippet in `FirebaseAdmin.Snippets/` to demonstrate the new feature. |
| 71 | + |
| 72 | +### Journey 2: How to Deprecate a Field/Method in an Existing API |
| 73 | + |
| 74 | +1. **Add Deprecation Note**: Locate where the deprecated object is defined and add a deprecation warning with a note (e.g. [Obsolete("Use X instead")]). |
| 75 | +2. **Remove Releted Tests and Update Snippets**: Because `Obsolete` warnings result in build errors, tests and snippets where the object is used should be removed or updated not no longer used the deprecated object. |
| 76 | + |
| 77 | +## Critical Do's and Don'ts |
| 78 | + |
| 79 | +- **DO**: Use the centralized `HttpClient` for all API calls. |
| 80 | +- **DO**: Follow the established `async`/`await` patterns for asynchronous code. |
| 81 | +- **DON'T**: Expose types from the `FirebaseAdmin/FirebaseAdmin/Utils/` directory in any public API. |
| 82 | +- **DON'T**: Introduce new third-party dependencies without a compelling reason and discussion with the maintainers. |
| 83 | + |
| 84 | +## Commit and Pull Request Generation |
| 85 | + |
| 86 | +After implementing and testing a change, you must create a commit and Pull Request following these rules: |
| 87 | + |
| 88 | +**1. Commit Message Format**: The commit message is critical and is used to generate the Pull Request. It MUST follow this structure: |
| 89 | + - **Title**: Use the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification: `type(scope): subject`. |
| 90 | + - `scope` should be the service package changed (e.g., `auth`, `rtdb`, `deps`). |
| 91 | + - **Note on Scopes**: Some services use specific abbreviations. Use the abbreviation if one exists. Common abbreviations include: |
| 92 | + - `messaging` -> `fcm` |
| 93 | + - `dataconnect` -> `fdc` |
| 94 | + - `database` -> `rtdb` |
| 95 | + - `appcheck` -> `fac` |
| 96 | + - Example: `fix(auth): Resolve issue with custom token verification` |
| 97 | + - Example: `feat(fcm): Add support for multicast messages` |
| 98 | + - **Body**: The body is separated from the title by a blank line and MUST contain the following, in order: |
| 99 | + 1. A brief explanation of the problem and the solution. |
| 100 | + 2. A summary of the testing strategy (e.g., "Added a new unit test to verify the fix."). |
| 101 | + 3. A **Context Sources** section that lists the `id` and repository path of every `AGENTS.md` file you used to verify context usage. |
| 102 | + |
| 103 | +**2. Example Commit Message**: |
| 104 | + ``` |
| 105 | + feat(fcm): Add support for multicast messages |
| 106 | +
|
| 107 | + This change introduces a new `SendEachForMulticastAsync` method to the messaging client, allowing developers to send a single message to multiple tokens efficiently. |
| 108 | +
|
| 109 | + Testing: Added unit tests with a mock server and an integration test in `FirebaseAdmin.IntegrationTests/MessagingTest.cs`. |
| 110 | +
|
| 111 | + Context Sources Used: |
| 112 | + - id: firebase-admin-dotnet |
| 113 | + - id: firebase-admin-dotnet-messaging |
| 114 | + ``` |
| 115 | + |
| 116 | +**3. Pull Request**: The Pull Request title and description should be populated directly from the commit message's title and body. |
| 117 | + |
| 118 | +## Metadata: |
| 119 | +- id: firebase-admin-dotnet |
0 commit comments