Skip to content

Commit 15f819f

Browse files
committed
Merge branch 'main' into update-cpp-style-guide
2 parents 45c2a5a + 2af9185 commit 15f819f

File tree

8 files changed

+1125
-143
lines changed

8 files changed

+1125
-143
lines changed

Jules.md renamed to AGENTS.md

Lines changed: 114 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Introduction
22

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+
37
This document provides context and guidance for AI agents (like Jules) when
48
making changes to the Firebase C++ SDK repository. It covers essential
59
information about the repository's structure, setup, testing procedures, API
@@ -29,11 +33,11 @@ instructions for your specific platform.
2933
* **CMake**: Version 3.7 or newer.
3034
* **Python**: Version 3.7 or newer.
3135
* **Abseil-py**: Python package.
32-
* **OpenSSL**: Required for Realtime Database and Cloud Firestore
33-
(especially for desktop builds).
34-
* **Android SDK & NDK**: Required for building Android libraries.
35-
`sdkmanager` can be used for installation. CMake for Android (version
36-
3.10.2 recommended) is also needed.
36+
* **OpenSSL**: Required for Realtime Database and Cloud Firestore (especially
37+
for desktop builds).
38+
* **Android SDK & NDK**: Required for building Android libraries. `sdkmanager`
39+
can be used for installation. CMake for Android (version 3.10.2
40+
recommended) is also needed.
3741
* **(Windows Only) Strings**: From Microsoft Sysinternals, required for
3842
Android builds on Windows.
3943
* **Cocoapods**: Required for building iOS or tvOS libraries.
@@ -79,8 +83,7 @@ When setting up for desktop, if you are using an iOS
7983
`GoogleService-Info.plist` file, convert it to the required
8084
`google-services-desktop.json` using the script:
8185
`python generate_xml_from_google_services_json.py --plist -i GoogleService-Info.plist`
82-
(run this from the script's directory, ensuring the plist file is
83-
accessible).
86+
(run this from the script's directory, ensuring the plist file is accessible).
8487

8588
The desktop SDK searches for configuration files in the current working
8689
directory, first for `google-services-desktop.json`, then for
@@ -177,10 +180,10 @@ Database).
177180
* `firebase::AppOptions` can be used to configure the app with
178181
specific parameters if not relying on a `google-services.json` or
179182
`GoogleService-Info.plist` file.
180-
2. **Service Instances**: Once `firebase::App` is initialized, you
181-
generally obtain instances of specific Firebase services using a static
182-
`GetInstance()` method on the service's class, passing the
183-
`firebase::App` object.
183+
2. **Service Instances**: Once `firebase::App` is initialized, you generally
184+
obtain instances of specific Firebase services using a static
185+
`GetInstance()` method on the service's class, passing the `firebase::App`
186+
object.
184187
* Examples for services like Auth, Database, Storage, Firestore:
185188
* `firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app, &init_result);`
186189
* `firebase::database::Database* database = firebase::database::Database::GetInstance(app, &init_result);`
@@ -192,11 +195,11 @@ Database).
192195
a different pattern. Analytics is typically initialized with
193196
`firebase::analytics::Initialize(const firebase::App& app)` (often
194197
handled automatically for the default `App` instance). After this,
195-
Analytics functions (e.g., `firebase::analytics::LogEvent(...)`)
196-
are called as global functions within the `firebase::analytics`
197-
namespace, rather than on an instance object obtained via
198-
`GetInstance()`. Refer to the specific product's header file for
199-
its exact initialization mechanism if it deviates from the common
198+
Analytics functions (e.g., `firebase::analytics::LogEvent(...)`) are
199+
called as global functions within the `firebase::analytics` namespace,
200+
rather than on an instance object obtained via `GetInstance()`.
201+
Refer to the specific product's header file for its exact
202+
initialization mechanism if it deviates from the common
200203
`GetInstance(app, ...)` pattern.
201204

202205
### Asynchronous Operations: `firebase::Future<T>`
@@ -311,9 +314,15 @@ detailed API documentation.
311314
[STYLE_GUIDE.md](STYLE_GUIDE.md).
312315
* **Google C++ Style Guide**: Adhere to the
313316
[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
314-
as mentioned in `CONTRIBUTING.md` for general C++ style.
315-
* **Formatting**: Use `python3 scripts/format_code.py -git_diff -verbose`
316-
to format your code before committing.
317+
as mentioned in `CONTRIBUTING.md`.
318+
* **Formatting**: Use `python3 scripts/format_code.py -git_diff -verbose` to
319+
format your code before committing.
320+
* **Naming Precision for Dynamic Systems**: Function names should precisely
321+
reflect their behavior, especially in systems with dynamic or asynchronous
322+
interactions. For example, a function that processes a list of items should
323+
be named differently from one that operates on a single, specific item
324+
captured asynchronously. Regularly re-evaluate function names as
325+
requirements evolve to maintain clarity.
317326

318327
## Comments
319328

@@ -360,20 +369,26 @@ detailed API documentation.
360369
* **Pointers**: Standard C++ smart pointers (`std::unique_ptr`,
361370
`std::shared_ptr`) should be used where appropriate for managing
362371
dynamically allocated memory.
363-
* **`Future` Lifecycle**: Ensure `Future` objects returned from API
364-
calls are properly managed. While `Future`s handle their own internal
365-
memory for the result, the asynchronous operations they represent
366-
need to complete to reliably free all associated operational
367-
resources or to ensure actions (like writes to a database) are
368-
definitely finalized. Abandoning a `Future` (letting it go out of
369-
scope without checking its result, attaching an `OnCompletion`
370-
callback, or explicitly `Wait()`ing for it) can sometimes lead to
371-
operations not completing as expected or resources not being cleaned
372-
up promptly by the underlying services, especially if the `Future` is
373-
the only handle to that operation. Prefer using `OnCompletion` or
374-
otherwise ensuring the `Future` completes its course, particularly
375-
for operations with side effects or those that allocate significant
376-
backend resources.
372+
* **`Future` Lifecycle**: Ensure `Future` objects returned from API calls are
373+
properly managed. While `Future`s handle their own internal memory for the
374+
result, the asynchronous operations they represent need to complete to
375+
reliably free all associated operational resources or to ensure actions
376+
(like writes to a database) are definitely finalized. Abandoning a `Future`
377+
(letting it go out of scope without checking its result, attaching an
378+
`OnCompletion` callback, or explicitly `Wait()`ing for it) can sometimes
379+
lead to operations not completing as expected or resources not being
380+
cleaned up promptly by the underlying services, especially if the `Future`
381+
is the only handle to that operation. Prefer using `OnCompletion` or
382+
otherwise ensuring the `Future` completes its course, particularly for
383+
operations with side effects or those that allocate significant backend
384+
resources.
385+
* **Lifecycle of Queued Callbacks/Blocks**: If blocks or callbacks are queued
386+
to be run upon an asynchronous event (e.g., an App Delegate class being set
387+
or a Future completing), clearly define and document their lifecycle.
388+
Determine if they are one-shot (cleared after first execution) or
389+
persistent (intended to run for multiple or future events). This impacts
390+
how associated data and the blocks themselves are stored and cleared,
391+
preventing memory leaks or unexpected multiple executions.
377392

378393
## Immutability
379394

@@ -406,10 +421,33 @@ detailed API documentation.
406421
indexes, queries may fail or not return expected results.
407422
* **iOS Method Swizzling**: Be aware that some Firebase products on iOS
408423
(e.g., Dynamic Links, Cloud Messaging) use method swizzling to
409-
automatically attach handlers to your `AppDelegate`. While this
410-
simplifies integration, it can occasionally be a factor to consider
411-
when debugging app delegate behavior or integrating with other
412-
libraries that also perform swizzling.
424+
automatically attach handlers to your `AppDelegate`. While this simplifies
425+
integration, it can occasionally be a factor to consider when debugging app
426+
delegate behavior or integrating with other libraries that also perform
427+
swizzling.
428+
When implementing or interacting with swizzling, especially for App Delegate
429+
methods like `[UIApplication setDelegate:]`:
430+
* Be highly aware that `setDelegate:` can be called multiple times
431+
with different delegate class instances, including proxy classes
432+
from other libraries (e.g., GUL - Google Utilities). Swizzling
433+
logic must be robust against being invoked multiple times for the
434+
same effective method on the same class or on classes in a
435+
hierarchy. An idempotency check (i.e., if the method's current IMP
436+
is already the target swizzled IMP, do nothing more for that
437+
specific swizzle attempt) in any swizzling utility can prevent
438+
issues like recursion.
439+
* When tracking unique App Delegate classes (e.g., for applying hooks
440+
or callbacks via swizzling), consider the class hierarchy. If a
441+
superclass has already been processed, processing a subclass for
442+
the same inherited methods might be redundant or problematic. A
443+
strategy to check if a newly set delegate is a subclass of an
444+
already processed delegate can prevent such issues.
445+
* For code that runs very early in the application lifecycle on
446+
iOS/macOS (e.g., `+load` methods, static initializers involved in
447+
swizzling), prefer using `NSLog` directly over custom logging
448+
frameworks if there's any uncertainty about whether the custom
449+
framework is fully initialized, to avoid crashes during logging
450+
itself.
413451

414452
## Class and File Structure
415453

@@ -548,11 +586,11 @@ prevent memory leaks, dangling pointers, or double deletions.
548586

549587
# Updating This Document
550588

551-
This document is a living guide. As the Firebase C++ SDK evolves, new
552-
patterns may emerge, or existing practices might change. If you introduce
553-
a new common pattern, significantly alter a build process, or establish a
554-
new best practice during your work, please take a moment to update this
555-
`Jules.md` file accordingly.
589+
This document is a living guide. As the Firebase C++ SDK evolves, new patterns
590+
may emerge, or existing practices might change. If you introduce a new common
591+
pattern, significantly alter a build process, or establish a new best practice
592+
during your work, please take a moment to update this `AGENTS.md` file
593+
accordingly.
556594

557595
Keeping this document current will greatly benefit future AI agents and
558596
human developers working on this repository.
@@ -561,41 +599,43 @@ human developers working on this repository.
561599

562600
## Recommended General Prompt Instruction
563601

564-
When working on this task, please consistently refer to the `Jules.md`
565-
guide for all repository-specific conventions, including setup
566-
procedures, coding style, common architectural patterns, and API usage.
567-
Pay close attention to the testing strategies outlined, ensuring your
568-
implementation includes comprehensive integration tests with detailed test
569-
cases in your plan. Implement robust error handling for any new or
570-
modified public API methods, following the patterns for `firebase::Future`
571-
error reporting. If the feature involves platform-specific code, ensure
572-
the public API remains consistent across all platforms, as discussed in
573-
`Jules.md`. Write clear, maintainable code, adhering to the commenting
574-
guidelines, and if you need to add new third-party dependencies, document
575-
the rationale and update build configurations according to the established
576-
practices. Ensure your changes align with the overall best practices
577-
detailed in `Jules.md`.
602+
When working on this task, please consistently refer to the `AGENTS.md` guide
603+
for all repository-specific conventions, including setup procedures, coding
604+
style, common architectural patterns, and API usage. Pay close attention to the
605+
testing strategies outlined, ensuring your implementation includes
606+
comprehensive integration tests with detailed test cases in your plan. Implement
607+
robust error handling for any new or modified public API methods, following the
608+
patterns for `firebase::Future` error reporting. If the feature involves
609+
platform-specific code, ensure the public API remains consistent across all
610+
platforms, as discussed in `AGENTS.md`. Write clear, maintainable code,
611+
adhering to the commenting guidelines, and if you need to add new third-party
612+
dependencies, document the rationale and update build configurations according
613+
to the established practices. Ensure your changes align with the overall best
614+
practices detailed in `AGENTS.md`.
578615

579616
## Key Directives for Jules AI
580617

581-
* **Prioritize `Jules.md`**: This document (`Jules.md`) contains
582-
repository-specific guidelines. Prioritize this information when
583-
making decisions about coding style, testing procedures,
584-
architectural patterns, and API usage.
585-
* **Adherence to Patterns**: Strive to follow the common patterns and
586-
best practices outlined here. This ensures consistency across the
587-
codebase.
588-
* **Clarification for Deviations**: If the existing patterns in
589-
`Jules.md` do not seem suitable for a specific task, or if a
590-
deviation is necessary, please explicitly state this in your plan or
591-
request clarification before proceeding with implementation.
592-
* **Updating `Jules.md`**: If you introduce a new, broadly applicable
593-
pattern, or if a significant change to the build process or best
594-
practices occurs as part of your task, please include a step in your
595-
plan to update `Jules.md` to reflect these changes.
618+
* **Prioritize `AGENTS.md`**: This document (`AGENTS.md`) contains
619+
repository-specific guidelines. Prioritize this information when making
620+
decisions about coding style, testing procedures, architectural patterns,
621+
and API usage.
622+
* **Adherence to Patterns**: Strive to follow the common patterns and best
623+
practices outlined here. This ensures consistency across the codebase.
624+
* **Clarification for Deviations**: If the existing patterns in `AGENTS.md` do
625+
not seem suitable for a specific task, or if a deviation is necessary,
626+
please explicitly state this in your plan or request clarification before
627+
proceeding with implementation.
628+
* **Updating `AGENTS.md`**: If you introduce a new, broadly applicable
629+
pattern, or if a significant change to the build process or best practices
630+
occurs as part of your task, please include a step in your plan to update
631+
`AGENTS.md` to reflect these changes.
596632
* **Testing**: Remember that integration tests are the primary method of
597-
testing. Ensure new features are accompanied by corresponding
598-
integration tests as described in the 'Testing' section of
599-
`Jules.md`.
633+
testing. Ensure new features are accompanied by corresponding integration
634+
tests as described in the 'Testing' section of `AGENTS.md`.
600635
* **Commit Messages**: Follow standard commit message guidelines. A brief
601636
summary line, followed by a more detailed explanation if necessary.
637+
* **Tool Limitations & Path Specificity**: If codebase search tools (like
638+
`grep` or recursive `ls`) are limited or unavailable, and initial attempts
639+
to locate files/modules based on common directory structures are
640+
unsuccessful, explicitly ask for more specific paths rather than assuming a
641+
module doesn't exist or contains no relevant code.

app/src/invites/ios/invites_ios_startup.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ @implementation UIApplication (FIRFBI)
286286
+ (void)load {
287287
// C++ constructors may not be called yet so call NSLog rather than LogDebug.
288288
NSLog(@"Loading UIApplication category for Firebase App");
289-
::firebase::util::ForEachAppDelegateClass(^(Class clazz) {
289+
::firebase::util::RunOnAppDelegateClasses(^(Class clazz) {
290290
::firebase::invites::HookAppDelegateMethods(clazz);
291291
});
292292
}

app/src/util_ios.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,12 @@ typedef BOOL (
185185
id self, SEL selector_value, UIApplication *application,
186186
NSUserActivity *user_activity, void (^restoration_handler)(NSArray *));
187187

188-
// Call the given block once for every Objective-C class that exists that
189-
// implements the UIApplicationDelegate protocol (except for those in a
190-
// blacklist we keep).
191-
void ForEachAppDelegateClass(void (^block)(Class));
188+
// Calls the given block for each unique Objective-C class that has been
189+
// previously passed to [UIApplication setDelegate:]. The block is executed
190+
// immediately for all currently known unique delegate classes.
191+
// Additionally, the block is queued to be executed if any new, unique
192+
// Objective-C class is passed to [UIApplication setDelegate:] in the future.
193+
void RunOnAppDelegateClasses(void (^block)(Class));
192194

193195
// Convert a string array into an NSMutableArray.
194196
NSMutableArray *StringVectorToNSMutableArray(

0 commit comments

Comments
 (0)