diff --git a/Android/firebase_dependencies.gradle b/Android/firebase_dependencies.gradle
index 57cf7152a7..d1a2ecde24 100644
--- a/Android/firebase_dependencies.gradle
+++ b/Android/firebase_dependencies.gradle
@@ -20,8 +20,8 @@ def firebaseDependenciesMap = [
'admob' : ['com.google.firebase:firebase-ads:18.2.0',
'com.google.android.gms:play-services-measurement-sdk-api:17.2.0'],
'analytics' : ['com.google.firebase:firebase-analytics:17.2.0'],
- 'auth' : ['com.google.firebase:firebase-auth:19.0.0'],
- 'database' : ['com.google.firebase:firebase-database:19.1.0'],
+ 'auth' : ['com.google.firebase:firebase-auth:19.1.0'],
+ 'database' : ['com.google.firebase:firebase-database:19.2.0'],
'dynamic_links' : ['com.google.firebase:firebase-dynamic-links:19.0.0'],
'functions' : ['com.google.firebase:firebase-functions:19.0.1'],
'instance_id' : ['com.google.firebase:firebase-iid:20.0.0'],
@@ -29,9 +29,9 @@ def firebaseDependenciesMap = [
// Messaging has an additional local dependency to include.
'messaging' : ['com.google.firebase:firebase-messaging:20.0.0',
'firebase_cpp_sdk.messaging:messaging_java'],
- 'performance' : ['com.google.firebase:firebase-perf:19.0.0'],
- 'remote_config' : ['com.google.firebase:firebase-config:19.0.1'],
- 'storage' : ['com.google.firebase:firebase-storage:19.0.1']
+ 'performance' : ['com.google.firebase:firebase-perf:19.0.1'],
+ 'remote_config' : ['com.google.firebase:firebase-config:19.0.3'],
+ 'storage' : ['com.google.firebase:firebase-storage:19.1.0']
]
// A map of library to the gradle resources that they depend upon.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0c819fa430..6708d35ab8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,12 @@ option(FIREBASE_CPP_BUILD_TESTS
option(FIREBASE_FORCE_FAKE_SECURE_STORAGE
"Disable use of platform secret store and use fake impl." OFF)
+if(WIN32)
+ # Turn on the use of the __cplusplus compiler define that is used to detect if
+ # move operators are supported
+ add_definitions("/Zc:__cplusplus")
+endif()
+
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_CURRENT_LIST_DIR}/cmake)
include(external_rules)
diff --git a/README.md b/README.md
index f4a20515b4..0b509a8111 100644
--- a/README.md
+++ b/README.md
@@ -49,20 +49,61 @@ git clone https://github.com/firebase/firebase-cpp-sdk.git
## Prerequisites
The following prerequisites are required for all platforms. Be sure to add any
directories to your PATH as needed.
+
- [CMake](https://cmake.org/), version 3.1, or newer
-- [Python](https://www.python.com/), the latest version of 2.7, or newer
+- [Python2](https://www.python.com/), version of 2.7, or newer
- [Abseil-py](https://github.com/abseil/abseil-py)
+Note: Once python is installed you can use the following commands to install
+required packages:
+
+* python -m ensurepip --default-pip
+* python -m pip install --user absl-py
+* python -m pip install --user protobuf
+
### Prerequisites for Desktop
The following prerequisites are required when building the libraries for
desktop platforms.
+
- [OpenSSL](https://www.openssl.org/), needed for Realtime Database
- [Protobuf](https://github.com/protocolbuffers/protobuf/blob/master/src/README.md),
needed for Remote Config
+### Prerequisites for Windows
+Prebuilt packages for openssl can be found using google and if CMake fails to
+find the install path use the command line option
+**-DOPENSSL_ROOT_DIR=[Open SSL Dir]**.
+
+Since there are no prebuilt packages for protobuf, getting it working on Windows
+is a little tricky. The following steps can be used as a guide:
+
+* Download source [zip from github](https://github.com/protocolbuffers/protobuf/releases/download/v3.9.2/protobuf-all-3.9.2.zip).
+* Extract source and open command prompt to root folder
+* Make new folder **vsprojects**
+* CD to **vsprojects**
+* run cmake: **cmake ..\cmake -Dprotobuf_BUILD_TESTS=OFF -A Win32**
+* Build solution
+* Add command line define to firebase cmake command (see below)
+ **-DPROTOBUF_SRC_ROOT_FOLDER=[Source Root Folder]**
+
+Note: For x64 builds folder needs to be **vsprojects\x64** and change **Win32**
+in cmake command to **x64**
+
+### Prerequisites for Mac
+Home brew can be used to install required dependencies:
+
+```bash
+# https://github.com/protocolbuffers/protobuf/blob/master/kokoro/macos/prepare_build_macos_rc#L20
+ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+source $HOME/.rvm/scripts/rvm
+brew install cmake protobuf python2
+sudo chown -R $(whoami) /usr/local
+```
+
### Prerequisites for Android
The following prerequisites are required when building the libraries for
Android.
+
- Android SDK, Android NDK, and CMake for Android (version 3.10.2 recommended)
- Download sdkmanager (either independently, or as a part of Android Studio)
[here](https://developer.android.com/studio/#downloads)
diff --git a/admob/CMakeLists.txt b/admob/CMakeLists.txt
index 06c19e58cf..d070679f07 100644
--- a/admob/CMakeLists.txt
+++ b/admob/CMakeLists.txt
@@ -17,7 +17,9 @@
cmake_minimum_required (VERSION 3.1)
set (CMAKE_CXX_STANDARD 11)
+include(binary_to_array)
include(download_pod_headers)
+include(firebase_cpp_gradle)
project(firebase_admob NONE)
enable_language(C)
@@ -36,6 +38,8 @@ set(common_SRCS
src/common/rewarded_video_internal.cc)
# Define the resource build needed for Android
+firebase_cpp_gradle(":admob:admob_resources:generateDexJarRelease"
+ "${CMAKE_CURRENT_LIST_DIR}/admob_resources/build/dexed.jar")
binary_to_array("admob_resources"
"${CMAKE_CURRENT_LIST_DIR}/admob_resources/build/dexed.jar"
"firebase_admob"
@@ -107,7 +111,9 @@ else()
add_definitions(-include assert.h -include string.h)
endif()
-if(IOS)
+if(ANDROID)
+ firebase_cpp_proguard_file(admob)
+elseif(IOS)
# AdMob for iOS uses weak references, which requires enabling Automatic
# Reference Counting (ARC).
set_property(
@@ -119,7 +125,7 @@ if(IOS)
set(pod_target_name "download_admob_pod_headers")
set(pods_dir "${PROJECT_BINARY_DIR}/Pods")
set(pod_list "")
- list(APPEND pod_list "'Firebase/AdMob', '6.9.0'")
+ list(APPEND pod_list "'Firebase/AdMob', '6.10.0'")
setup_pod_headers_target("${pod_target_name}" "${pods_dir}" "${pod_list}")
@@ -129,6 +135,14 @@ if(IOS)
PRIVATE
${base_header_dir}/Google-Mobile-Ads-SDK
)
+ string(CONCAT google_mobile_ads_framework_path
+ "${pods_dir}/Pods/Google-Mobile-Ads-SDK/"
+ "Frameworks/GoogleMobileAdsFramework-Current/GoogleMobileAds.framework")
+ # AdMob expects the header files to be in a subfolder, so set up a symlink to
+ # accomplish that.
+ symlink_framework_headers(firebase_admob ${pod_target_name}
+ ${google_mobile_ads_framework_path} GoogleMobileAds
+ )
# Add a dependency to downloading the headers onto admob.
add_dependencies(firebase_admob ${pod_target_name})
diff --git a/admob/admob_resources/AndroidManifest.xml b/admob/admob_resources/AndroidManifest.xml
new file mode 100644
index 0000000000..02feeb8dfa
--- /dev/null
+++ b/admob/admob_resources/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/admob/admob_resources/build.gradle b/admob/admob_resources/build.gradle
index 930a9be5e4..a1fe4705d3 100644
--- a/admob/admob_resources/build.gradle
+++ b/admob/admob_resources/build.gradle
@@ -36,7 +36,7 @@ android {
sourceSets {
main {
- manifest.srcFile '../../android_build_files/AndroidManifest.xml'
+ manifest.srcFile 'AndroidManifest.xml'
java {
srcDirs = ['../src_java/com/google/firebase/admob/internal/cpp']
}
diff --git a/analytics/CMakeLists.txt b/analytics/CMakeLists.txt
index 7580a19a64..dad33a3c77 100644
--- a/analytics/CMakeLists.txt
+++ b/analytics/CMakeLists.txt
@@ -18,6 +18,7 @@ cmake_minimum_required (VERSION 3.1)
set (CMAKE_CXX_STANDARD 11)
include(download_pod_headers)
+include(firebase_cpp_gradle)
project(firebase_analytics NONE)
enable_language(C)
@@ -121,7 +122,9 @@ else()
add_definitions(-include assert.h -include string.h)
endif()
-if(IOS)
+if(ANDROID)
+ firebase_cpp_proguard_file(analytics)
+elseif(IOS)
# Enable Automatic Reference Counting (ARC).
set_property(
TARGET firebase_analytics
@@ -132,17 +135,19 @@ if(IOS)
set(pod_target_name "download_analytics_pod_headers")
set(pods_dir "${PROJECT_BINARY_DIR}/Pods")
set(pod_list "")
- list(APPEND pod_list "'Firebase/Core', '6.9.0'")
- list(APPEND pod_list "'Firebase/Analytics', '6.9.0'")
+ list(APPEND pod_list "'Firebase/Core', '6.10.0'")
+ list(APPEND pod_list "'Firebase/Analytics', '6.10.0'")
setup_pod_headers_target("${pod_target_name}" "${pods_dir}" "${pod_list}")
# Add the Cocoapod headers to the include directories
set(base_header_dir "${pods_dir}/Pods/Headers/Public")
+ set(analytics_framework_path
+ "${pods_dir}/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework")
target_include_directories(firebase_analytics
PRIVATE
${base_header_dir}/FirebaseCore
- ${base_header_dir}/FirebaseAnalytics/FirebaseAnalytics
+ ${analytics_framework_path}/Headers
)
# Add a dependency to downloading the headers onto analytics.
diff --git a/analytics/src/analytics_android.cc b/analytics/src/analytics_android.cc
index e024a15e68..22b89166a3 100644
--- a/analytics/src/analytics_android.cc
+++ b/analytics/src/analytics_android.cc
@@ -397,7 +397,7 @@ Future GetAnalyticsInstanceId() {
util::RegisterCallbackOnTask(
env, task,
[](JNIEnv* env, jobject result, util::FutureResult result_code,
- int status, const char* status_message, void* callback_data) {
+ const char* status_message, void* callback_data) {
auto* future_data = internal::FutureData::Get();
if (future_data) {
bool success =
diff --git a/analytics/src/analytics_ios.mm b/analytics/src/analytics_ios.mm
index e87c951b7a..1bfaab490f 100644
--- a/analytics/src/analytics_ios.mm
+++ b/analytics/src/analytics_ios.mm
@@ -24,19 +24,103 @@
#include "app/src/include/firebase/version.h"
#include "app/src/assert.h"
#include "app/src/log.h"
+#include "app/src/mutex.h"
+#include "app/src/time.h"
+#include "app/src/thread.h"
+#include "app/src/util.h"
#include "app/src/util_ios.h"
namespace firebase {
namespace analytics {
+// Used to workaround b/143656277 and b/110166640
+class AnalyticsDataResetter {
+ private:
+ enum ResetState {
+ kResetStateNone = 0,
+ kResetStateRequested,
+ kResetStateRetry,
+ };
+ public:
+ // Initialize the class.
+ AnalyticsDataResetter() : reset_state_(kResetStateNone), reset_timestamp_(0) {}
+
+ // Reset analytics data.
+ void Reset() {
+ MutexLock lock(mutex_);
+ reset_timestamp_ = firebase::internal::GetTimestampEpoch();
+ reset_state_ = kResetStateRequested;
+ instance_id_ = util::StringFromNSString([FIRAnalytics appInstanceID]);
+ [FIRAnalytics resetAnalyticsData];
+ }
+
+ // Get the instance ID, returning a non-empty string if it's valid or an empty string if it's
+ // still being reset.
+ std::string GetInstanceId() {
+ MutexLock lock(mutex_);
+ std::string current_instance_id = util::StringFromNSString([FIRAnalytics appInstanceID]);
+ uint64_t reset_time_elapsed_milliseconds = GetResetTimeElapsedMilliseconds();
+ switch (reset_state_) {
+ case kResetStateNone:
+ break;
+ case kResetStateRequested:
+ if (reset_time_elapsed_milliseconds >= kResetRetryIntervalMilliseconds) {
+ // Firebase Analytics on iOS can take a while to initialize, in this case we try to reset
+ // again if the instance ID hasn't changed for a while.
+ reset_state_ = kResetStateRetry;
+ reset_timestamp_ = firebase::internal::GetTimestampEpoch();
+ [FIRAnalytics resetAnalyticsData];
+ return std::string();
+ }
+ FIREBASE_CASE_FALLTHROUGH;
+
+ case kResetStateRetry:
+ if ((current_instance_id.empty() || current_instance_id == instance_id_) &&
+ reset_time_elapsed_milliseconds < kResetTimeoutMilliseconds) {
+ return std::string();
+ }
+ break;
+ }
+ instance_id_ = current_instance_id;
+ return current_instance_id;
+ }
+
+ private:
+ // Get the time elapsed in milliseconds since reset was requested.
+ uint64_t GetResetTimeElapsedMilliseconds() const {
+ return firebase::internal::GetTimestampEpoch() - reset_timestamp_;
+ }
+
+ private:
+ Mutex mutex_;
+ // Reset attempt.
+ ResetState reset_state_;
+ // When a reset was last requested.
+ uint64_t reset_timestamp_;
+ // Instance ID before it was reset.
+ std::string instance_id_;
+
+ // Time to wait before trying to reset again.
+ static const uint64_t kResetRetryIntervalMilliseconds;
+ // Time to wait before giving up on resetting the ID.
+ static const uint64_t kResetTimeoutMilliseconds;
+};
+
DEFINE_FIREBASE_VERSION_STRING(FirebaseAnalytics);
+const uint64_t AnalyticsDataResetter::kResetRetryIntervalMilliseconds = 1000;
+const uint64_t AnalyticsDataResetter::kResetTimeoutMilliseconds = 5000;
+
static const double kMillisecondsPerSecond = 1000.0;
+static Mutex g_mutex; // NOLINT
static bool g_initialized = false;
+static AnalyticsDataResetter *g_resetter = nullptr;
// Initialize the API.
void Initialize(const ::firebase::App& app) {
+ MutexLock lock(g_mutex);
g_initialized = true;
+ g_resetter = new AnalyticsDataResetter();
internal::RegisterTerminateOnDefaultAppDestroy();
internal::FutureData::Create();
}
@@ -50,8 +134,11 @@ void Initialize(const ::firebase::App& app) {
// Terminate the API.
void Terminate() {
+ MutexLock lock(g_mutex);
internal::FutureData::Destroy();
internal::UnregisterTerminateOnDefaultAppDestroy();
+ delete g_resetter;
+ g_resetter = nullptr;
g_initialized = false;
}
@@ -169,22 +256,40 @@ void SetCurrentScreen(const char* screen_name, const char* screen_class) {
}
void ResetAnalyticsData() {
+ MutexLock lock(g_mutex);
FIREBASE_ASSERT_RETURN_VOID(internal::IsInitialized());
- [FIRAnalytics resetAnalyticsData];
+ g_resetter->Reset();
}
Future GetAnalyticsInstanceId() {
+ MutexLock lock(g_mutex);
FIREBASE_ASSERT_RETURN(Future(), internal::IsInitialized());
auto* api = internal::FutureData::Get()->api();
const auto future_handle = api->SafeAlloc(
internal::kAnalyticsFnGetAnalyticsInstanceId);
- api->CompleteWithResult(
- future_handle, 0, "",
- util::StringFromNSString([FIRAnalytics appInstanceID]));
+ static int kPollTimeMs = 100;
+ Thread get_id_thread([](SafeFutureHandle* handle) {
+ for ( ; ; ) {
+ {
+ MutexLock lock(g_mutex);
+ if (!internal::IsInitialized()) break;
+ std::string instance_id = g_resetter->GetInstanceId();
+ if (!instance_id.empty()) {
+ internal::FutureData::Get()->api()->CompleteWithResult(
+ *handle, 0, "", instance_id);
+ break;
+ }
+ }
+ firebase::internal::Sleep(kPollTimeMs);
+ }
+ delete handle;
+ }, new SafeFutureHandle(future_handle));
+ get_id_thread.Detach();
return Future(api, future_handle.get());
}
Future GetAnalyticsInstanceIdLastResult() {
+ MutexLock lock(g_mutex);
FIREBASE_ASSERT_RETURN(Future(), internal::IsInitialized());
return static_cast&>(
internal::FutureData::Get()->api()->LastResult(
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 453a49c48d..3cca895f7b 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -20,6 +20,7 @@ set (CMAKE_CXX_STANDARD 11)
include(FindPkgConfig)
include(binary_to_array)
include(download_pod_headers)
+include(firebase_cpp_gradle)
project(firebase_app NONE)
enable_language(C)
@@ -32,14 +33,20 @@ binary_to_array("google_services_resource"
"${FIREBASE_GEN_FILE_DIR}/app")
# Define the resource builds needed for Android
+firebase_cpp_gradle(":app:app_resources:generateDexJarRelease"
+ "${CMAKE_CURRENT_LIST_DIR}/app_resources/build/dexed.jar")
binary_to_array("app_resources"
"${CMAKE_CURRENT_LIST_DIR}/app_resources/build/dexed.jar"
"firebase_app"
"${FIREBASE_GEN_FILE_DIR}/app")
+firebase_cpp_gradle(":app:google_api_resources:generateDexJarRelease"
+ "${CMAKE_CURRENT_LIST_DIR}/google_api_resources/build/dexed.jar")
binary_to_array("google_api_resources"
"${CMAKE_CURRENT_LIST_DIR}/google_api_resources/build/dexed.jar"
"google_api"
"${FIREBASE_GEN_FILE_DIR}/app")
+firebase_cpp_gradle(":app:invites_resources:generateDexJarRelease"
+ "${CMAKE_CURRENT_LIST_DIR}/invites_resources/build/dexed.jar")
binary_to_array("invites_resources"
"${CMAKE_CURRENT_LIST_DIR}/invites_resources/build/dexed.jar"
"firebase_invites"
@@ -340,7 +347,9 @@ if(MSVC)
add_definitions(-DNOMINMAX)
endif()
-if(IOS)
+if(ANDROID)
+ firebase_cpp_proguard_file(app)
+elseif(IOS)
# Enable Automatic Reference Counting (ARC).
set_property(
TARGET firebase_app
@@ -351,8 +360,8 @@ if(IOS)
set(pod_target_name "download_app_pod_headers")
set(pods_dir "${PROJECT_BINARY_DIR}/Pods")
set(pod_list "")
- list(APPEND pod_list "'Firebase/Core', '6.9.0'")
- list(APPEND pod_list "'Firebase/DynamicLinks', '6.9.0'")
+ list(APPEND pod_list "'Firebase/Core', '6.10.0'")
+ list(APPEND pod_list "'Firebase/DynamicLinks', '6.10.0'")
setup_pod_headers_target("${pod_target_name}" "${pods_dir}" "${pod_list}")
diff --git a/app/rest/controller_curl.cc b/app/rest/controller_curl.cc
index 1057ab598a..b61608a210 100644
--- a/app/rest/controller_curl.cc
+++ b/app/rest/controller_curl.cc
@@ -45,11 +45,11 @@ ControllerCurl::~ControllerCurl() {
}
#if defined(FIREBASE_USE_MOVE_OPERATORS) || defined(DOXYGEN)
-ControllerCurl::ControllerCurl(ControllerCurl&& other) {
+ControllerCurl::ControllerCurl(ControllerCurl&& other) noexcept {
*this = std::move(other);
}
-ControllerCurl& ControllerCurl::operator=(ControllerCurl&& other) {
+ControllerCurl& ControllerCurl::operator=(ControllerCurl&& other) noexcept {
direction_ = other.direction_;
transport_ = other.transport_;
is_paused_ = other.is_paused_;
diff --git a/app/rest/controller_curl.h b/app/rest/controller_curl.h
index 53343be599..9edbdc4001 100644
--- a/app/rest/controller_curl.h
+++ b/app/rest/controller_curl.h
@@ -54,9 +54,9 @@ class ControllerCurl : public Controller {
~ControllerCurl() override;
#if defined(FIREBASE_USE_MOVE_OPERATORS) || defined(DOXYGEN)
- ControllerCurl(ControllerCurl&& other);
+ ControllerCurl(ControllerCurl&& other) noexcept;
- ControllerCurl& operator=(ControllerCurl&& other);
+ ControllerCurl& operator=(ControllerCurl&& other) noexcept;
#endif // defined(FIREBASE_USE_MOVE_OPERATORS) || defined(DOXYGEN)
// Pauses whatever the handle is doing.
diff --git a/app/src/app_android.cc b/app/src/app_android.cc
index f4e63f8a66..8ffb1f3896 100644
--- a/app/src/app_android.cc
+++ b/app/src/app_android.cc
@@ -420,7 +420,7 @@ AppOptions* AppOptions::LoadDefault(AppOptions* app_options,
return app_options;
}
-App::App() : activity_(nullptr), internal_(nullptr) {}
+void App::Initialize() {}
App::~App() {
app_common::RemoveApp(this);
diff --git a/app/src/app_common.cc b/app/src/app_common.cc
index e1a2eae5b2..3c8a12d2d1 100644
--- a/app/src/app_common.cc
+++ b/app/src/app_common.cc
@@ -46,6 +46,17 @@
namespace FIREBASE_NAMESPACE {
+#ifdef FIREBASE_LINUX_BUILD_CONFIG_STRING
+void CheckCompilerString(const char* input) {
+ FIREBASE_ASSERT_MESSAGE(
+ strcmp(FIREBASE_LINUX_BUILD_CONFIG_STRING, input) == 0,
+ "The compiler or stdlib library Firebase was compiled with does not "
+ "match what is being used to compile this application."
+ " [Lib: '%s' != Bin: '%s']",
+ FIREBASE_LINUX_BUILD_CONFIG_STRING, input);
+}
+#endif // FIREBASE_LINUX_BUILD_CONFIG_STRING
+
// Default app name.
const char* const kDefaultAppName = "__FIRAPP_DEFAULT";
diff --git a/app/src/app_desktop.cc b/app/src/app_desktop.cc
index 2ac8e95126..eaa57873c8 100644
--- a/app/src/app_desktop.cc
+++ b/app/src/app_desktop.cc
@@ -117,7 +117,7 @@ AppOptions* AppOptions::LoadDefault(AppOptions* options) {
return nullptr;
}
-App::App() {
+void App::Initialize() {
internal_ = new internal::AppInternal();
}
diff --git a/app/src/app_ios.mm b/app/src/app_ios.mm
index 32c7caac00..11e50d4332 100644
--- a/app/src/app_ios.mm
+++ b/app/src/app_ios.mm
@@ -220,7 +220,7 @@ static void PlatformOptionsToAppOptions(FIROptions* platform_options,
return app_options;
}
-App::App() : internal_(nullptr) {}
+void App::Initialize() {}
App::~App() {
app_common::RemoveApp(this);
diff --git a/app/src/app_stub.cc b/app/src/app_stub.cc
index 7275d52204..69347aa653 100644
--- a/app/src/app_stub.cc
+++ b/app/src/app_stub.cc
@@ -31,7 +31,8 @@ DEFINE_FIREBASE_VERSION_STRING(Firebase);
const char* const kDefaultAppName = "default";
-App::App() : data_(new internal::FunctionRegistry) {
+void App::Initialize() {
+ data_ = new internal::FunctionRegistry;
LogDebug("Creating firebase::App for %s", kFirebaseVersionString);
}
diff --git a/app/src/include/firebase/app.h b/app/src/include/firebase/app.h
index 2e9a63f2be..d8967515eb 100644
--- a/app/src/include/firebase/app.h
+++ b/app/src/include/firebase/app.h
@@ -39,6 +39,11 @@
namespace FIREBASE_NAMESPACE {
+#ifdef FIREBASE_LINUX_BUILD_CONFIG_STRING
+// Check to see if the shared object compiler string matches the input
+void CheckCompilerString(const char* input);
+#endif // FIREBASE_LINUX_BUILD_CONFIG_STRING
+
// Predeclarations.
#ifdef INTERNAL_EXPERIMENTAL
namespace internal {
@@ -754,7 +759,21 @@ class App {
private:
/// Construct the object.
- App();
+ App() :
+#if FIREBASE_PLATFORM_ANDROID || defined(DOXYGEN)
+ activity_(nullptr),
+#endif
+ internal_(nullptr) {
+ Initialize();
+
+#ifdef FIREBASE_LINUX_BUILD_CONFIG_STRING
+ CheckCompilerString(FIREBASE_LINUX_BUILD_CONFIG_STRING);
+#endif // FIREBASE_LINUX_BUILD_CONFIG_STRING
+ }
+
+
+ /// Initialize internal implementation
+ void Initialize();
#ifndef SWIG
//
diff --git a/app/src/include/firebase/future.h b/app/src/include/firebase/future.h
index 93ff9b5d9d..b4e8b2c92a 100644
--- a/app/src/include/firebase/future.h
+++ b/app/src/include/firebase/future.h
@@ -117,10 +117,10 @@ class FutureBase {
/// Move constructor and operator.
/// Move is more efficient than copy and delete because we don't touch the
/// reference counting in the API.
- FutureBase(FutureBase&& rhs);
+ FutureBase(FutureBase&& rhs) noexcept;
/// Copy an untyped future.
- FutureBase& operator=(FutureBase&& rhs);
+ FutureBase& operator=(FutureBase&& rhs) noexcept;
#endif // defined(FIREBASE_USE_MOVE_OPERATORS)
/// Explicitly release the internal resources for a future.
@@ -188,13 +188,7 @@ class FutureBase {
/// @param[in] callback Function pointer to your callback.
/// @param[in] user_data Optional user data. We will pass this back to your
/// callback.
-#if defined(INTERNAL_EXPERIMENTAL)
- /// @return A handle that can be passed to RemoveOnCompletion.
- CompletionCallbackHandle
-#else
- void
-#endif
- OnCompletion(CompletionCallback callback, void* user_data) const;
+ void OnCompletion(CompletionCallback callback, void* user_data) const;
#if defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
/// Register a single callback that will be called at most once, when the
@@ -216,13 +210,7 @@ class FutureBase {
///
/// @note This method is not available when using STLPort on Android, as
/// `std::function` is not supported on STLPort.
-#if defined(INTERNAL_EXPERIMENTAL)
- /// @return A handle that can be passed to RemoveOnCompletion.
- CompletionCallbackHandle
-#else
- void
-#endif
- OnCompletion(std::function callback) const;
+ void OnCompletion(std::function callback) const;
#endif // defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
#if defined(INTERNAL_EXPERIMENTAL)
@@ -267,10 +255,10 @@ class FutureBase {
#endif // defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
/// Unregisters a callback that was previously registered with
- /// AddOnCompletion or OnCompletion.
+ /// AddOnCompletion.
///
/// @param[in] completion_handle The return value of a previous call to
- /// AddOnCompletion or OnCompletion.
+ /// AddOnCompletion.
void RemoveOnCompletion(CompletionCallbackHandle completion_handle) const;
#endif // defined(INTERNAL_EXPERIMENTAL)
@@ -421,12 +409,7 @@ class Future : public FutureBase {
/// @note This is the same callback as FutureBase::OnCompletion(), so you
/// can't expect to set both and have both run; again, only the most recently
/// registered one will run.
-#if defined(INTERNAL_EXPERIMENTAL)
- /// @return A handle that can be passed to RemoveOnCompletion.
- inline CompletionCallbackHandle
-#else
inline void
-#endif
OnCompletion(TypedCompletionCallback callback, void* user_data) const;
#if defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
@@ -444,12 +427,7 @@ class Future : public FutureBase {
/// @note This is the same callback as FutureBase::OnCompletion(), so you
/// can't expect to set both and have both run; again, only the most recently
/// registered one will run.
-#if defined(INTERNAL_EXPERIMENTAL)
- /// @return A handle that can be passed to RemoveOnCompletion.
- inline CompletionCallbackHandle
-#else
inline void
-#endif
OnCompletion(std::function&)> callback) const;
#endif // defined(FIREBASE_USE_STD_FUNCTION) || defined(DOXYGEN)
diff --git a/app/src/include/firebase/internal/common.h b/app/src/include/firebase/internal/common.h
index 01e11f4feb..b2952f2e78 100644
--- a/app/src/include/firebase/internal/common.h
+++ b/app/src/include/firebase/internal/common.h
@@ -23,10 +23,12 @@
#include
// Move operators use rvalue references, which are a C++11 extension.
+// Also, Visual Studio 2010 and later actually support move operators despite
+// reporting __cplusplus to be 199711L, so explicitly check for that.
// Also, stlport doesn't implement std::move().
-#if __cplusplus >= 201103L && !defined(_STLPORT_VERSION)
+#if (__cplusplus >= 201103L || _MSC_VER >= 1600) && !defined(_STLPORT_VERSION)
#define FIREBASE_USE_MOVE_OPERATORS
-#endif // __cplusplus >= 201103L && !defined(_STLPORT_VERSION)
+#endif
// stlport doesn't implement std::function.
#if !defined(_STLPORT_VERSION)
diff --git a/app/src/include/firebase/internal/future_impl.h b/app/src/include/firebase/internal/future_impl.h
index a16039d862..6ed34479ae 100644
--- a/app/src/include/firebase/internal/future_impl.h
+++ b/app/src/include/firebase/internal/future_impl.h
@@ -162,34 +162,15 @@ class CompletionCallbackHandle {
} // namespace detail
-#ifdef INTERNAL_EXPERIMENTAL
template
-FutureBase::CompletionCallbackHandle
-Future::OnCompletion(
- TypedCompletionCallback callback, void* user_data) const {
- return FutureBase::OnCompletion(
- reinterpret_cast(callback), user_data);
-}
-#else
void
-template
Future::OnCompletion(
TypedCompletionCallback callback, void* user_data) const {
FutureBase::OnCompletion(
reinterpret_cast(callback), user_data);
}
-#endif
#if defined(FIREBASE_USE_STD_FUNCTION)
-#if defined(INTERNAL_EXPERIMENTAL)
-template
-inline FutureBase::CompletionCallbackHandle
-Future::OnCompletion(
- std::function&)> callback) const {
- return FutureBase::OnCompletion(
- *reinterpret_cast*>(&callback));
-}
-#else
template
inline void
Future::OnCompletion(
@@ -197,7 +178,6 @@ Future::OnCompletion(
FutureBase::OnCompletion(
*reinterpret_cast*>(&callback));
}
-#endif
#endif // defined(FIREBASE_USE_STD_FUNCTION)
#if defined(INTERNAL_EXPERIMENTAL)
@@ -251,7 +231,7 @@ inline FutureBase& FutureBase::operator=(const FutureBase& rhs) {
}
#if defined(FIREBASE_USE_MOVE_OPERATORS)
-inline FutureBase::FutureBase(FutureBase&& rhs)
+inline FutureBase::FutureBase(FutureBase&& rhs) noexcept
: api_(NULL) // NOLINT
{
detail::UnregisterForCleanup(rhs.api_, &rhs);
@@ -259,7 +239,7 @@ inline FutureBase::FutureBase(FutureBase&& rhs)
detail::RegisterForCleanup(api_, this);
}
-inline FutureBase& FutureBase::operator=(FutureBase&& rhs) {
+inline FutureBase& FutureBase::operator=(FutureBase&& rhs) noexcept {
Release();
detail::UnregisterForCleanup(rhs.api_, &rhs);
api_ = rhs.api_;
@@ -296,16 +276,6 @@ inline const void* FutureBase::result_void() const {
return api_ == NULL ? NULL : api_->GetFutureResult(handle_); // NOLINT
}
-#if defined(INTERNAL_EXPERIMENTAL)
-inline FutureBase::CompletionCallbackHandle FutureBase::OnCompletion(
- CompletionCallback callback, void* user_data) const {
- if (api_ != NULL) { // NOLINT
- return api_->AddCompletionCallback(handle_, callback, user_data, nullptr,
- /*clear_existing_callbacks=*/ true);
- }
- return CompletionCallbackHandle();
-}
-#else
inline void FutureBase::OnCompletion(CompletionCallback callback,
void* user_data) const {
if (api_ != NULL) { // NOLINT
@@ -313,7 +283,6 @@ inline void FutureBase::OnCompletion(CompletionCallback callback,
/*clear_existing_callbacks=*/ true);
}
}
-#endif
#if defined(INTERNAL_EXPERIMENTAL)
inline FutureBase::CompletionCallbackHandle
@@ -335,16 +304,6 @@ inline void FutureBase::RemoveOnCompletion(
#endif // defined(INTERNAL_EXPERIMENTAL)
#if defined(FIREBASE_USE_STD_FUNCTION)
-#if defined(INTERNAL_EXPERIMENTAL)
-inline FutureBase::CompletionCallbackHandle FutureBase::OnCompletion(
- std::function callback) const {
- if (api_ != NULL) { // NOLINT
- return api_->AddCompletionCallbackLambda(handle_, callback,
- /*clear_existing_callbacks=*/ true);
- }
- return CompletionCallbackHandle();
-}
-#else
inline void FutureBase::OnCompletion(
std::function callback) const {
if (api_ != NULL) { // NOLINT
@@ -352,7 +311,6 @@ inline void FutureBase::OnCompletion(
/*clear_existing_callbacks=*/ true);
}
}
-#endif
#if defined(INTERNAL_EXPERIMENTAL)
inline FutureBase::CompletionCallbackHandle FutureBase::AddOnCompletion(
diff --git a/app/src/include/firebase/internal/platform.h b/app/src/include/firebase/internal/platform.h
index 0d5c947442..e2518195ae 100644
--- a/app/src/include/firebase/internal/platform.h
+++ b/app/src/include/firebase/internal/platform.h
@@ -65,6 +65,37 @@
#define FIREBASE_PLATFORM_UNKNOWN 1
#endif
+#if FIREBASE_PLATFORM_LINUX
+
+// Include std library header to get version defines
+#include
+
+#if defined(__clang__)
+#define FIREBASE_COMPILER_CLANG 1
+#elif defined(__GNUC__)
+#define FIREBASE_COMPILER_GCC 1
+#endif
+
+#if defined(_LIBCPP_VERSION)
+#define FIREBASE_STANDARD_LIBCPP 1
+#elif defined(__GLIBCXX__)
+#define FIREBASE_STANDARD_LIBSTDCPP 1
+#endif
+
+#if (FIREBASE_COMPILER_CLANG && FIREBASE_STANDARD_LIBCPP)
+#define FIREBASE_LINUX_BUILD_CONFIG_STRING "clang_libstdcpp"
+#elif (FIREBASE_COMPILER_CLANG && FIREBASE_STANDARD_LIBSTDCPP)
+#define FIREBASE_LINUX_BUILD_CONFIG_STRING "clang_libcpp"
+#elif (FIREBASE_COMPILER_GCC && FIREBASE_STANDARD_LIBCPP)
+#define FIREBASE_LINUX_BUILD_CONFIG_STRING "gcc_libstdcpp"
+#elif (FIREBASE_COMPILER_GCC && FIREBASE_STANDARD_LIBSTDCPP)
+#define FIREBASE_LINUX_BUILD_CONFIG_STRING "gcc_libcpp"
+#else
+#error "Unsupported compiler or standard library"
+#endif
+
+#endif // FIREBASE_PLATFORM_LINUX
+
#define FIREBASE_PLATFORM_MOBILE \
(FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_ANDROID)
#define FIREBASE_PLATFORM_DESKTOP \
diff --git a/app/src/include/firebase/variant.h b/app/src/include/firebase/variant.h
index 2547f4ea14..4314b0b426 100644
--- a/app/src/include/firebase/variant.h
+++ b/app/src/include/firebase/variant.h
@@ -18,11 +18,13 @@
#define FIREBASE_APP_CLIENT_CPP_SRC_INCLUDE_FIREBASE_VARIANT_H_
#include
+
#include
#include