Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Bug] Unable to Fetch Updated Data from Firebase Remote Config without Restart

Open
#1,630 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
cpp, firebase
Domain
cloud

Research direction

Start with the Firebase C++ quickstart remote_config/testapp and the modified common_main.cc shown in the report. Run the reproduction with minimum_fetch_interval_in_milliseconds set to 0, call Fetch(0), change the console value, and compare repeated fetch and Activate results. Done means updated Remote Config data is returned without restarting the application.

Written by the indexing model from the issue text.

Description

api: auth new type: question
[REQUIRED] Please fill in the following fields:
  • Pre-built SDK from the open-source from this repo: https://github.com/firebase/firebase-cpp-sdk/releases/tag/v12.0.0
  • Firebase C++ SDK version: 12.0.0
  • Problematic Firebase Component: Remote Config (Auth, Database, etc.)
  • Other Firebase Components in use: No (Auth, Database, etc.)
  • Platform you are using the C++ SDK on: Mac (Mac, Windows, or Linux)
  • Platform you are targeting: desktop (iOS, Android, and/or desktop)
[REQUIRED] Please describe the issue here:

We are experiencing an issue where our application is unable to fetch updated data from Firebase Remote Config. Despite setting the .minimum_fetch_interval_in_milliseconds to 0 and calling Fetch(0), the application continues to retrieve outdated data until it is restarted.

According to the source code, these steps should be sufficient to fetch the new data immediately. However, changes made to the Firebase Remote Config are not reflected in the app until a restart is performed.

In the attached example (a modified example from https://github.com/firebase/quickstart-cpp/tree/main/remote_config/testapp), I have added 5 attempts to fetch new data with a delay. During the timeout, I change values in the remote config. Below is the output log from the example

Steps to reproduce:
  1. Set up Firebase Remote Config from https://github.com/firebase/quickstart-cpp/tree/main/remote_config/testapp.
  2. Change common_main.cc to provided below or from attached archive.
  3. Set .minimum_fetch_interval_in_milliseconds = 0.
  4. Call Fetch(0) to fetch new data.
  5. Change values in the Firebase Remote Config console.
  6. Attempt to fetch the updated data multiple times with a delay between each attempt.
  7. Observe that the fetched data remains the same (old data) until the application is restarted.

Have you been able to reproduce this issue with just the Firebase C++ quickstarts ?
Yes
What's the issue repro rate? (e g 100%, 1/5 etc)
100%

What happened? How can we make the problem occur?

Initialize the Firebase Remote Config library
Created the Firebase app f3405e80
Try to initialize Firebase RemoteConfig
Initialized the Firebase Remote Config API
Changed ConfigSettings minimum_fetch_interval_in_milliseconds to 0
Fetch...
Fetch Complete
Activate succeeded
Info last_fetch_time_ms=-468513974 (year=2024.60) fetch_status=0 failure_reason=0 throttled_end_time=0
Get test_key "test changed" Remote
GetKeys:
  test_key
Fetch...
Fetch Complete
Activate succeeded
Info last_fetch_time_ms=-468493069 (year=2024.60) fetch_status=0 failure_reason=0 throttled_end_time=0
Get test_key "test changed" Remote
GetKeys:
  test_key
Fetch...
Fetch Complete
Activate succeeded
Info last_fetch_time_ms=-468472180 (year=2024.60) fetch_status=0 failure_reason=0 throttled_end_time=0
Get test_key "test changed" Remote
GetKeys:
  test_key
Relevant Code:
// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <assert.h>

#include "firebase/app.h"
#include "firebase/remote_config.h"
#include "firebase/util.h"

// Thin OS abstraction layer.
#include "main.h" // NOLINT

using firebase::remote_config::RemoteConfig;

// Convert remote_config::ValueSource to a string.
const char *ValueSourceToString(firebase::remote_config::ValueSource source)
{
  static const char *kSourceToString[] = {
      "Static",  // kValueSourceStaticValue
      "Remote",  // kValueSourceRemoteValue
      "Default", // kValueSourceDefaultValue
  };
  return kSourceToString[source];
}

RemoteConfig *rc_ = nullptr;

// Execute all methods of the C++ Remote Config API.
extern "C" int common_main(int argc, const char *argv[])
{
  namespace remote_config = ::firebase::remote_config;
  ::firebase::App *app;

  // Initialization

  firebase::AppOptions options;
  // Fill options
  // options.set_api_key("");
  // options.set_app_id("");
  // options.set_project_id("");
  // options.set_storage_bucket("");
  // options.set_messaging_sender_id("");

  LogMessage("Initialize the Firebase Remote Config library");
#if defined(__ANDROID__)
  app = ::firebase::App::Create(GetJniEnv(), GetActivity());
#else
  app = ::firebase::App::Create(options);
#endif // defined(__ANDROID__)

  LogMessage("Created the Firebase app %x",
             static_cast<int>(reinterpret_cast<intptr_t>(app)));

  ::firebase::ModuleInitializer initializer;

  void *ptr = nullptr;
  ptr = &rc_;
  initializer.Initialize(app, ptr, [](::firebase::App *app, void *target)
                         {
    LogMessage("Try to initialize Firebase RemoteConfig");
    RemoteConfig **rc_ptr = reinterpret_cast<RemoteConfig **>(target);
    *rc_ptr = RemoteConfig::GetInstance(app);
    return firebase::kInitResultSuccess; });

  while (initializer.InitializeLastResult().status() !=
         firebase::kFutureStatusComplete)
  {
    if (ProcessEvents(100))
      return 1; // exit if requested
  }

  if (initializer.InitializeLastResult().error() != 0)
  {
    LogMessage("Failed to initialize Firebase Remote Config: %s",
               initializer.InitializeLastResult().error_message());
    ProcessEvents(2000);
    return 1;
  }

  LogMessage("Initialized the Firebase Remote Config API");

  auto config_settings_result = rc_->SetConfigSettings(
      {.fetch_timeout_in_milliseconds =
           firebase::remote_config::kDefaultTimeoutInMilliseconds,
       .minimum_fetch_interval_in_milliseconds = 0});

  while (config_settings_result.status() == firebase::kFutureStatusPending)
  {
    if (ProcessEvents(1000))
    {
      break;
    }
  }

  LogMessage("Changed ConfigSettings minimum_fetch_interval_in_milliseconds to 0");

  auto tryWithDelay = [&]()
  {
    // Test Fetch...
    LogMessage("Fetch...");
    auto future_result = rc_->Fetch(0);
    while (future_result.status() == firebase::kFutureStatusPending)
    {
      if (ProcessEvents(1000))
      {
        break;
      }
    }

    if (future_result.status() == firebase::kFutureStatusComplete)
    {
      LogMessage("Fetch Complete");
      auto activate_future_result = rc_->Activate();
      while (future_result.status() == firebase::kFutureStatusPending)
      {
        if (ProcessEvents(1000))
        {
          break;
        }
      }

      bool activate_result = activate_future_result.result();
      LogMessage("Activate %s", activate_result ? "succeeded" : "failed");

      const remote_config::ConfigInfo &info = rc_->GetInfo();
      LogMessage("Info last_fetch_time_ms=%d (year=%.2f) fetch_status=%d "
                 "failure_reason=%d throttled_end_time=%d",
                 static_cast<int>(info.fetch_time),
                 1970.0f + static_cast<float>(info.fetch_time) /
                               (1000.0f * 60.0f * 60.0f * 24.0f * 365.0f),
                 info.last_fetch_status, info.last_fetch_failure_reason,
                 info.throttled_end_time);

      remote_config::ValueInfo value_info;
      std::string result = rc_->GetString("test_key", &value_info);
      LogMessage("Get test_key \"%s\" %s", result.c_str(),
                 ValueSourceToString(value_info.source));

      {
        // Print out the keys that are now tied to data
        std::vector<std::string> keys = rc_->GetKeys();
        LogMessage("GetKeys:");
        for (auto s = keys.begin(); s != keys.end(); ++s)
        {
          LogMessage("  %s", s->c_str());
        }
      }
    }
    else
    {
      LogMessage("Fetch Incomplete");
    }
    // Release a handle to the future so we can shutdown the Remote Config API
    // when exiting the app.  Alternatively we could have placed future_result
    // in a scope different to our shutdown code below.
    future_result.Release();
  };

  for (int i = 5; i > 0; --i)
  {
    tryWithDelay();
    ProcessEvents(20000);
  }

  // Wait until the user wants to quit the app.
  while (!ProcessEvents(1000))
  {
  }

  delete rc_;
  rc_ = nullptr;
  delete app;

  return 0;
}

quickstart-cpp-main.zip

Dominant language
C++
Stars
326
Forks
138
Avg merge
2d 16h
Merged PRs (30d)
3

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from firebase/firebase-cpp-sdk

All issues in firebase/firebase-cpp-sdk

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.