1
1
# Introduction
2
2
3
+ > ** Note on Document Formatting:** This document (` AGENTS.md ` ) should be
4
+ > maintained with lines word-wrapped to a maximum of 80 characters to ensure
5
+ > readability across various editors and terminals.
6
+
3
7
This document provides context and guidance for AI agents (like Jules) when
4
8
making changes to the Firebase C++ SDK repository. It covers essential
5
9
information about the repository's structure, setup, testing procedures, API
@@ -34,8 +38,8 @@ instructions for your specific platform.
34
38
* ** Android SDK & NDK** : Required for building Android libraries. ` sdkmanager `
35
39
can be used for installation. CMake for Android (version 3.10.2
36
40
recommended) is also needed.
37
- * ** (Windows Only) Strings** : From Microsoft Sysinternals, required for Android
38
- builds on Windows.
41
+ * ** (Windows Only) Strings** : From Microsoft Sysinternals, required for
42
+ Android builds on Windows.
39
43
* ** Cocoapods** : Required for building iOS or tvOS libraries.
40
44
41
45
## Building the SDK
@@ -74,9 +78,10 @@ generated in each library's build directory (e.g.,
74
78
75
79
### Desktop Platform Setup Details
76
80
77
- When setting up for desktop, if you are using an iOS ` GoogleService-Info.plist `
78
- file, convert it to the required ` google-services-desktop.json ` using the
79
- script: ` python generate_xml_from_google_services_json.py --plist -i GoogleService-Info.plist `
81
+ When setting up for desktop, if you are using an iOS
82
+ ` GoogleService-Info.plist ` file, convert it to the required
83
+ ` google-services-desktop.json ` using the script:
84
+ ` python generate_xml_from_google_services_json.py --plist -i GoogleService-Info.plist `
80
85
(run this from the script's directory, ensuring the plist file is accessible).
81
86
82
87
The desktop SDK searches for configuration files in the current working
@@ -175,8 +180,9 @@ Database).
175
180
parameters if not relying on a ` google-services.json ` or
176
181
` GoogleService-Info.plist ` file.
177
182
2 . ** Service Instances** : Once ` firebase::App ` is initialized, you generally
178
- obtain instances of specific Firebase services using a static ` GetInstance() `
179
- method on the service's class, passing the ` firebase::App ` object.
183
+ obtain instances of specific Firebase services using a static
184
+ ` GetInstance() ` method on the service's class, passing the ` firebase::App `
185
+ object.
180
186
* Examples for services like Auth, Database, Storage, Firestore:
181
187
* ` firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app, &init_result); `
182
188
* ` firebase::database::Database* database = firebase::database::Database::GetInstance(app, &init_result); `
@@ -192,8 +198,8 @@ Database).
192
198
called as global functions within the ` firebase::analytics ` namespace,
193
199
rather than on an instance object obtained via ` GetInstance() ` .
194
200
Refer to the specific product's header file for its exact
195
- initialization mechanism if it deviates from the common ` GetInstance(app, ...) `
196
- pattern.
201
+ initialization mechanism if it deviates from the common
202
+ ` GetInstance(app, ...) ` pattern.
197
203
198
204
### Asynchronous Operations: ` firebase::Future<T> `
199
205
@@ -205,8 +211,8 @@ where `T` is the type of the expected result.
205
211
` kFutureStatusInvalid ` .
206
212
* ** Getting Results** : Once ` future.status() == kFutureStatusComplete ` :
207
213
* Check for errors: ` future.error() ` . A value of ` 0 ` (e.g.,
208
- ` firebase::auth::kAuthErrorNone ` , ` firebase::database::kErrorNone ` )
209
- usually indicates success.
214
+ ` firebase::auth::kAuthErrorNone ` ,
215
+ ` firebase::database::kErrorNone ` ) usually indicates success.
210
216
* Get the error message: ` future.error_message() ` .
211
217
* Get the result: ` future.result() ` . This returns a pointer to the result
212
218
object of type ` T ` . The result is only valid if ` future.error() `
@@ -218,8 +224,8 @@ where `T` is the type of the expected result.
218
224
219
225
### Core Classes and Operations (Examples from Auth and Database)
220
226
221
- While each Firebase product has its own specific classes, the following examples
222
- illustrate common API patterns:
227
+ While each Firebase product has its own specific classes, the following
228
+ examples illustrate common API patterns:
223
229
224
230
* ** ` firebase::auth::Auth ` ** : The main entry point for Firebase
225
231
Authentication.
@@ -308,6 +314,12 @@ API documentation.
308
314
as mentioned in ` CONTRIBUTING.md ` .
309
315
* ** Formatting** : Use ` python3 scripts/format_code.py -git_diff -verbose ` to
310
316
format your code before committing.
317
+ * ** Naming Precision for Dynamic Systems** : Function names should precisely
318
+ reflect their behavior, especially in systems with dynamic or asynchronous
319
+ interactions. For example, a function that processes a list of items should
320
+ be named differently from one that operates on a single, specific item
321
+ captured asynchronously. Regularly re-evaluate function names as
322
+ requirements evolve to maintain clarity.
311
323
312
324
## Comments
313
325
@@ -331,8 +343,9 @@ API documentation.
331
343
* ** Check ` Future ` status and errors** : Always check ` future.status() ` and
332
344
` future.error() ` before attempting to use ` future.result() ` .
333
345
* A common success code is ` 0 ` (e.g.,
334
- ` firebase::auth::kAuthErrorNone ` , ` firebase::database::kErrorNone ` ).
335
- Other specific error codes are defined per module (e.g.,
346
+ ` firebase::auth::kAuthErrorNone ` ,
347
+ ` firebase::database::kErrorNone ` ). Other specific error codes are
348
+ defined per module (e.g.,
336
349
` firebase::auth::kAuthErrorUserNotFound ` ).
337
350
* ** Callback error parameters** : When using listeners or other callbacks,
338
351
always check the provided error code and message before processing the
@@ -365,6 +378,13 @@ API documentation.
365
378
otherwise ensuring the ` Future ` completes its course, particularly for
366
379
operations with side effects or those that allocate significant backend
367
380
resources.
381
+ * ** Lifecycle of Queued Callbacks/Blocks** : If blocks or callbacks are queued
382
+ to be run upon an asynchronous event (e.g., an App Delegate class being set
383
+ or a Future completing), clearly define and document their lifecycle.
384
+ Determine if they are one-shot (cleared after first execution) or
385
+ persistent (intended to run for multiple or future events). This impacts
386
+ how associated data and the blocks themselves are stored and cleared,
387
+ preventing memory leaks or unexpected multiple executions.
368
388
369
389
## Immutability
370
390
@@ -400,6 +420,29 @@ API documentation.
400
420
integration, it can occasionally be a factor to consider when debugging app
401
421
delegate behavior or integrating with other libraries that also perform
402
422
swizzling.
423
+ When implementing or interacting with swizzling, especially for App Delegate
424
+ methods like ` [UIApplication setDelegate:] ` :
425
+ * Be highly aware that ` setDelegate: ` can be called multiple times
426
+ with different delegate class instances, including proxy classes
427
+ from other libraries (e.g., GUL - Google Utilities). Swizzling
428
+ logic must be robust against being invoked multiple times for the
429
+ same effective method on the same class or on classes in a
430
+ hierarchy. An idempotency check (i.e., if the method's current IMP
431
+ is already the target swizzled IMP, do nothing more for that
432
+ specific swizzle attempt) in any swizzling utility can prevent
433
+ issues like recursion.
434
+ * When tracking unique App Delegate classes (e.g., for applying hooks
435
+ or callbacks via swizzling), consider the class hierarchy. If a
436
+ superclass has already been processed, processing a subclass for
437
+ the same inherited methods might be redundant or problematic. A
438
+ strategy to check if a newly set delegate is a subclass of an
439
+ already processed delegate can prevent such issues.
440
+ * For code that runs very early in the application lifecycle on
441
+ iOS/macOS (e.g., ` +load ` methods, static initializers involved in
442
+ swizzling), prefer using ` NSLog ` directly over custom logging
443
+ frameworks if there's any uncertainty about whether the custom
444
+ framework is fully initialized, to avoid crashes during logging
445
+ itself.
403
446
404
447
## Class and File Structure
405
448
@@ -465,9 +508,9 @@ management:
465
508
module, but the fundamental responsibility for creation and deletion in
466
509
typical scenarios lies with the Pimpl class itself.
467
510
468
- It's crucial to correctly implement all these aspects (constructors, destructor,
469
- copy/move operators) when dealing with raw pointer Pimpls to prevent memory
470
- leaks, dangling pointers, or double deletions.
511
+ It's crucial to correctly implement all these aspects (constructors,
512
+ destructor, copy/move operators) when dealing with raw pointer Pimpls to
513
+ prevent memory leaks, dangling pointers, or double deletions.
471
514
472
515
## Namespace Usage
473
516
@@ -579,3 +622,8 @@ practices detailed in `AGENTS.md`.
579
622
tests as described in the 'Testing' section of ` AGENTS.md ` .
580
623
* ** Commit Messages** : Follow standard commit message guidelines. A brief
581
624
summary line, followed by a more detailed explanation if necessary.
625
+ * ** Tool Limitations & Path Specificity** : If codebase search tools (like
626
+ ` grep ` or recursive ` ls ` ) are limited or unavailable, and initial attempts
627
+ to locate files/modules based on common directory structures are
628
+ unsuccessful, explicitly ask for more specific paths rather than assuming a
629
+ module doesn't exist or contains no relevant code.
0 commit comments