Skip to content

Firebase Storage: Implement List and ListAll API for StorageReference #1726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

jonsimantov
Copy link
Contributor

Adds the List(max_results, page_token) and ListAll() methods to the firebase::storage::StorageReference C++ API.

These methods allow you to list objects and common prefixes (directories) within a storage location.

Features:

  • Paginated listing using List(max_results, page_token).
  • Comprehensive listing using ListAll().
  • Returns a Future<ListResult>, where ListResult contains a list of StorageReference objects for items and prefixes, and a page token for continuation.
  • Implemented for Android by calling the underlying Firebase Android SDK's list operations via JNI.
  • Implemented for iOS by calling the underlying Firebase iOS SDK's list operations.
  • Desktop platform provides stubs that return kErrorUnimplemented.
  • Includes comprehensive integration tests covering various scenarios such as basic listing, pagination, empty folders, and listing non-existent paths.

Description

Provide details of the change, and generalize the change in the PR title above.


Testing

Describe how you've tested these changes. Link any manually triggered Integration tests or CPP binary SDK Packaging Github Action workflows, if applicable.


Type of Change

Place an x the applicable box:

  • Bug fix. Add the issue # below if applicable.
  • New feature. A non-breaking change which adds functionality.
  • Other, such as a build process or documentation change.

Notes

  • Bug fixes and feature changes require an update to the Release Notes section of release_build_files/readme.md.
  • Read the contribution guidelines CONTRIBUTING.md.
  • Changes to the public API require an internal API review. If you'd like to help us make Firebase APIs better, please propose your change in a feature request so that we can discuss it together.

Adds the `List(max_results, page_token)` and `ListAll()` methods to the
`firebase::storage::StorageReference` C++ API.

These methods allow you to list objects and common prefixes (directories)
within a storage location.

Features:
- Paginated listing using `List(max_results, page_token)`.
- Comprehensive listing using `ListAll()`.
- Returns a `Future<ListResult>`, where `ListResult` contains a list of
  `StorageReference` objects for items and prefixes, and a page token
  for continuation.
- Implemented for Android by calling the underlying Firebase Android SDK's
  list operations via JNI.
- Implemented for iOS by calling the underlying Firebase iOS SDK's list
  operations.
- Desktop platform provides stubs that return `kErrorUnimplemented`.
- Includes comprehensive integration tests covering various scenarios such
  as basic listing, pagination, empty folders, and listing non-existent
  paths.
Copy link
Contributor Author

@jonsimantov jonsimantov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial comments.

@@ -1622,4 +1706,200 @@ TEST_F(FirebaseStorageTest, TestInvalidatingReferencesWhenDeletingApp) {
InitializeAppAndAuth();
}

TEST_F(FirebaseStorageTest, ListAllBasic) {
SKIP_TEST_ON_ANDROID_EMULATOR; // List tests can be slow on emulators or have quota issues.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a reason to skip this test on emulator yet, let's run it first and see.

}

TEST_F(FirebaseStorageTest, ListPaginated) {
SKIP_TEST_ON_ANDROID_EMULATOR;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, let's not skip on emulator for now.

protected:
// Root reference for list tests.
firebase::storage::StorageReference list_test_root_;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like adding this to the top-level testing fixture. I think each list test can just create its own folder. Also, UploadStringAsFile already adds all the uploaded files to the cleanup list, so I don't think there is any special cleanup needed here anyway.

#include "app/src/include/firebase/app.h"
#include "app/src/util_android.h"
#include "storage/src/android/storage_android.h"
#include "storage/src/android/storage_reference_android.h" // For StorageReferenceInternal constructor
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove these types of comments, in this repo we don't explain why we include each file in a comment, we just include it.

}

std::vector<StorageReference> ListResultInternal::items() const {
if (!list_result_java_ref_) return {};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically according to Google Code Style, simple lower-case accessors like items() and prefixes() should be low-cost operations. I think it would be appropriate here to only do the conversion from Java to C++ once and cache the results in the ListResultInternal.

Here's a summary of the changes:

- Integration Tests:
    - I removed `SKIP_TEST_ON_ANDROID_EMULATOR` from the `ListAllBasic` and `ListPaginated` tests.
    - I refactored the list tests so they create their own unique root folders instead of using a shared one in the test fixture. This improves test isolation.
- Code Style:
    - I removed unnecessary comments that were explaining header includes.
    - I removed placeholder comments from public headers.
    - I updated the copyright year to 2025 in all newly added files.
- Android Performance:
    - I optimized Android's `ListResultInternal` to cache converted items, prefixes, and the page token. This will avoid repeated JNI calls on subsequent accesses.
- Cleanup Mechanism:
    - I simplified the `ListResult` cleanup by removing the `ListResultInternalCommon` class. `ListResult` now directly manages the cleanup registration of its `internal_` member, similar to `StorageReference`.
Incorporates feedback from the initial review of the List API:

- Build Fix:
    - Explicitly namespaced StorageReference in list_result.h to resolve undeclared identifier error.
- Integration Tests:
    - Removed SKIP_TEST_ON_ANDROID_EMULATOR from ListAllBasic and ListPaginated tests.
    - Refactored list tests to create their own unique root folders instead of using a shared one in the test fixture, improving test isolation.
- Code Style:
    - Removed unnecessary comments explaining header includes.
    - Removed placeholder comments from public headers.
    - Updated copyright year to 2025 in all newly added files.
    - Ran code formatter (scripts/format_code.py -git_diff) on all changed files.
- Android Performance:
    - Optimized Android's ListResultInternal to cache converted items, prefixes, and page token. This avoids repeated JNI calls on subsequent accesses.
- Cleanup Mechanism:
    - Simplified ListResult cleanup by removing the ListResultInternalCommon class. ListResult now directly manages the cleanup registration of its internal_ member, similar to StorageReference.
…etween `storage_reference.h` and `list_result.h` by forward-declaring `ListResult` in `storage_reference.h`.

This commit also incorporates your previous feedback from the initial review of the List API:

- Build Fixes:
    - Forward-declared `ListResult` in `storage_reference.h`.
    - Reverted non-standard include placement in `list_result.h`.
    - Explicitly namespaced `StorageReference` in `list_result.h` (previous attempt, kept).
- Integration Tests:
    - Removed `SKIP_TEST_ON_ANDROID_EMULATOR` from `ListAllBasic` and `ListPaginated` tests.
    - Refactored list tests to create their own unique root folders instead of using a shared one in the test fixture, improving test isolation.
- Code Style:
    - Removed unnecessary comments explaining header includes.
    - Removed placeholder comments from public headers.
    - Updated copyright year to 2025 in all newly added files.
    - Ran the code formatter on all changed files.
- Android Performance:
    - Optimized Android's `ListResultInternal` to cache converted items, prefixes, and page token. This avoids repeated JNI calls on subsequent accesses.
- Cleanup Mechanism:
    - Simplified `ListResult` cleanup by removing the `ListResultInternalCommon` class. `ListResult` now directly manages the cleanup registration of its `internal_` member, similar to `StorageReference`.
@jonsimantov jonsimantov added the tests-requested: quick Trigger a quick set of integration tests. label Jun 10, 2025
@github-actions github-actions bot added tests: in-progress This PR's integration tests are in progress. and removed tests-requested: quick Trigger a quick set of integration tests. labels Jun 10, 2025
Copy link

github-actions bot commented Jun 10, 2025

❌  Integration test FAILED

Requested by @jonsimantov on commit 6b2f0d6
Last updated: Tue Jun 10 15:42 PDT 2025
View integration test log & download artifacts

Failures Configs
missing_log [TEST] [ERROR] [iOS] [macos] [All 2 ios_device]
[TEST] [ERROR] [tvOS] [macos] [tvos_simulator]
storage
(5 items)[BUILD] [ERROR] [Android] [All 3 os]
[BUILD] [ERROR] [Linux] [x64] [openssl]
[BUILD] [ERROR] [Windows] [x64] [openssl]
[BUILD] [ERROR] [iOS] [macos]
[BUILD] [ERROR] [tvOS] [macos]

Add flaky tests to go/fpl-cpp-flake-tracker

@github-actions github-actions bot added the tests: failed This PR's integration tests failed. label Jun 10, 2025
…ack for the List API.

Here's a summary of the changes:

I resolved build errors related to includes and circular dependencies for the Storage List API. Specifically:
- I fixed a circular include dependency between `storage_reference.h` and `list_result.h` by forward-declaring `ListResult` in `storage_reference.h`.
- I corrected the include path for platform-specific `StorageInternal` in `list_result.cc`.

This update also incorporates your previous feedback from the initial review:

- Build Fixes:
    - I forward-declared `ListResult` in `storage_reference.h`.
    - I reverted non-standard include placement in `list_result.h`.
    - I explicitly namespaced `StorageReference` in `list_result.h` (this was a previous attempt that I kept).
    - I corrected the `StorageInternal` include in `list_result.cc`.
- Integration Tests:
    - I removed `SKIP_TEST_ON_ANDROID_EMULATOR` from `ListAllBasic` and `ListPaginated` tests.
    - I refactored list tests to create their own unique root folders instead of using a shared one in the test fixture, which should improve test isolation.
- Code Style:
    - I removed unnecessary comments explaining header includes.
    - I removed placeholder comments from public headers.
    - I updated the copyright year to 2025 in all newly added files.
    - I applied code formatting to all changed files.
- Android Performance:
    - I optimized Android's `ListResultInternal` to cache converted items, prefixes, and page token. This should avoid repeated JNI calls on subsequent accesses.
- Cleanup Mechanism:
    - I simplified `ListResult` cleanup by removing the `ListResultInternalCommon` class. `ListResult` now directly manages the cleanup registration of its `internal_` member, similar to `StorageReference`.
@firebase-workflow-trigger firebase-workflow-trigger bot removed the tests: in-progress This PR's integration tests are in progress. label Jun 10, 2025
Corrects include directives for platform-specific StorageInternal
definitions in list_result_android.h, list_result_ios.h, and
list_result_desktop.h. Removes includes for the deleted
ListResultInternalCommon class.

This commit also incorporates previous feedback and build fixes:

- Build Fixes:
    - Resolved circular include dependency between storage_reference.h and
      list_result.h by forward-declaring ListResult in storage_reference.h.
    - Corrected includes in list_result.cc and platform-specific
      list_result_*.h files to use appropriate platform-specific
      headers for StorageInternal definitions.
- Integration Tests:
    - Removed SKIP_TEST_ON_ANDROID_EMULATOR from ListAllBasic and ListPaginated tests.
    - Refactored list tests to create their own unique root folders.
- Code Style:
    - Removed unnecessary comments.
    - Updated copyright years to 2025.
    - Ran code formatter on all changed files.
- Android Performance:
    - Optimized Android's ListResultInternal to cache converted data.
- Cleanup Mechanism:
    - Simplified ListResult cleanup logic.
Addresses all outstanding review comments and build errors for the
Storage List API feature. This includes:

- Build Fixes:
    - Resolved circular include dependency between storage_reference.h and
      list_result.h by forward-declaring ListResult in storage_reference.h.
    - Corrected includes in list_result.cc and platform-specific
      list_result_*.h files to use appropriate platform-specific
      headers for StorageInternal definitions.
- Code Cleanup:
    - Thoroughly removed commented-out code and unused includes.
    - Removed all explanatory comments next to #include directives.
    - Eliminated stray or development-related comments.
- Integration Tests:
    - Removed SKIP_TEST_ON_ANDROID_EMULATOR from ListAllBasic and ListPaginated tests.
    - Refactored list tests to create their own unique root folders.
- Code Style:
    - Updated copyright year to 2025 in all newly added files.
    - Ran code formatter (scripts/format_code.py -git_diff) on all changed files.
- Android Performance:
    - Optimized Android's ListResultInternal to cache converted data.
- Cleanup Mechanism:
    - Simplified ListResult cleanup logic by removing ListResultInternalCommon.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tests: failed This PR's integration tests failed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant