Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Commit 3db2b31

Browse files
author
amablue
committed
Added a Firebase Remote Config Cocos sample project.
PiperOrigin-RevId: 148166180
1 parent f5aa93c commit 3db2b31

File tree

7 files changed

+391
-4
lines changed

7 files changed

+391
-4
lines changed

messaging/Classes/FirebaseMessagingScene.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
USING_NS_CC;
3535

36+
3637
/// Padding for the UI elements.
3738
static const float kUIElementPadding = 10.0;
3839

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
// Copyright 2017 Google Inc. All rights reserved.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to
5+
// deal in the Software without restriction, including without limitation the
6+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7+
// sell copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16+
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#include "FirebaseRemoteConfigScene.h"
22+
23+
#include <stdarg.h>
24+
25+
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
26+
#include <android/log.h>
27+
#include <jni.h>
28+
#include "platform/android/jni/JniHelper.h"
29+
#endif
30+
31+
#include "FirebaseCocos.h"
32+
#include "firebase/remote_config.h"
33+
#include "firebase/variant.h"
34+
35+
USING_NS_CC;
36+
37+
/// Padding for the UI elements.
38+
static const float kUIElementPadding = 10.0;
39+
40+
/// Creates the Firebase scene.
41+
Scene* CreateFirebaseScene() {
42+
return FirebaseRemoteConfigScene::createScene();
43+
}
44+
45+
/// Creates the FirebaseRemoteConfigScene.
46+
Scene* FirebaseRemoteConfigScene::createScene() {
47+
// Create the scene.
48+
auto scene = Scene::create();
49+
50+
// Create the layer.
51+
auto layer = FirebaseRemoteConfigScene::create();
52+
53+
// Add the layer to the scene.
54+
scene->addChild(layer);
55+
56+
return scene;
57+
}
58+
59+
/// Initializes the FirebaseScene.
60+
bool FirebaseRemoteConfigScene::init() {
61+
namespace remote_config = ::firebase::remote_config;
62+
63+
if (!Layer::init()) {
64+
return false;
65+
}
66+
67+
auto visibleSize = Director::getInstance()->getVisibleSize();
68+
cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin();
69+
70+
// Create the Firebase label.
71+
auto firebaseLabel = Label::createWithTTF(
72+
"Firebase-RemoteConfig", "fonts/Marker Felt.ttf", 20);
73+
nextYPosition =
74+
origin.y + visibleSize.height - firebaseLabel->getContentSize().height;
75+
firebaseLabel->setPosition(
76+
cocos2d::Vec2(origin.x + visibleSize.width / 2, nextYPosition));
77+
this->addChild(firebaseLabel, 1);
78+
79+
const float scrollViewYPosition = nextYPosition -
80+
firebaseLabel->getContentSize().height -
81+
kUIElementPadding * 2;
82+
// Create the ScrollView on the Cocos2d thread.
83+
cocos2d::Director::getInstance()
84+
->getScheduler()
85+
->performFunctionInCocosThread(
86+
[=]() { this->createScrollView(scrollViewYPosition, 0.0f); });
87+
88+
// Intitialize Firebase RemoteConfig. (This must happen after the log ui
89+
// widget is set up so that the listener has a place to send log messages to).
90+
CCLOG("Initializing the RemoteConfig with Firebase API.");
91+
remote_config::Initialize(*firebase::App::GetInstance());
92+
93+
// Create the close app menu item.
94+
auto closeAppItem = MenuItemImage::create(
95+
"CloseNormal.png", "CloseSelected.png",
96+
CC_CALLBACK_1(FirebaseScene::menuCloseAppCallback, this));
97+
closeAppItem->setContentSize(cocos2d::Size(25, 25));
98+
// Position the close app menu item on the top-right corner of the screen.
99+
closeAppItem->setPosition(cocos2d::Vec2(
100+
origin.x + visibleSize.width - closeAppItem->getContentSize().width / 2,
101+
origin.y + visibleSize.height -
102+
closeAppItem->getContentSize().height / 2));
103+
104+
// Create the Menu for touch handling.
105+
auto menu = Menu::create(closeAppItem, NULL);
106+
menu->setPosition(cocos2d::Vec2::ZERO);
107+
this->addChild(menu, 1);
108+
109+
static const unsigned char kBinaryDefaults[] = {6, 0, 0, 6, 7, 3};
110+
111+
static const remote_config::ConfigKeyValueVariant defaults[] = {
112+
{"TestBoolean", true},
113+
{"TestLong", 42},
114+
{"TestDouble", 3.14},
115+
{"TestString", "Hello World"},
116+
{"TestData", firebase::Variant::FromStaticBlob(kBinaryDefaults,
117+
sizeof(kBinaryDefaults))}
118+
};
119+
size_t default_count = sizeof(defaults) / sizeof(defaults[0]);
120+
remote_config::SetDefaults(defaults, default_count);
121+
122+
// The return values may not be the set defaults, if a fetch was previously
123+
// completed for the app that set them.
124+
{
125+
bool result = remote_config::GetBoolean("TestBoolean");
126+
logMessage("Get TestBoolean %d", result ? 1 : 0);
127+
}
128+
{
129+
int64_t result = remote_config::GetLong("TestLong");
130+
logMessage("Get TestLong %lld", result);
131+
}
132+
{
133+
double result = remote_config::GetDouble("TestDouble");
134+
logMessage("Get TestDouble %f", result);
135+
}
136+
{
137+
std::string result = remote_config::GetString("TestString");
138+
logMessage("Get TestString %s", result.c_str());
139+
}
140+
{
141+
std::vector<unsigned char> result = remote_config::GetData("TestData");
142+
for (size_t i = 0; i < result.size(); ++i) {
143+
const unsigned char value = result[i];
144+
logMessage("TestData[%d] = 0x%02x", i, value);
145+
}
146+
}
147+
148+
// Enable developer mode and verified it's enabled.
149+
// NOTE: Developer mode should not be enabled in production applications.
150+
remote_config::SetConfigSetting(remote_config::kConfigSettingDeveloperMode,
151+
"1");
152+
if ((*remote_config::GetConfigSetting(
153+
remote_config::kConfigSettingDeveloperMode)
154+
.c_str()) != '1') {
155+
logMessage("Failed to enable developer mode");
156+
}
157+
158+
future_ = remote_config::Fetch(0);
159+
160+
// Schedule the update method for this scene.
161+
this->scheduleUpdate();
162+
163+
return true;
164+
}
165+
166+
// Called automatically every frame. The update is scheduled in `init()`.
167+
void FirebaseRemoteConfigScene::update(float /*delta*/) {
168+
namespace remote_config = ::firebase::remote_config;
169+
170+
if (future_.status() != firebase::kFutureStatusComplete) {
171+
return;
172+
}
173+
174+
logMessage("Fetch Complete");
175+
bool activate_result = remote_config::ActivateFetched();
176+
logMessage("ActivateFetched %s", activate_result ? "succeeded" : "failed");
177+
178+
const remote_config::ConfigInfo& info = remote_config::GetInfo();
179+
logMessage("Info last_fetch_time_ms=%d fetch_status=%d failure_reason=%d",
180+
static_cast<int>(info.fetch_time), info.last_fetch_status,
181+
info.last_fetch_failure_reason);
182+
183+
// Print out the new values, which may be updated from the Fetch.
184+
{
185+
bool result = remote_config::GetBoolean("TestBoolean");
186+
logMessage("Updated TestBoolean %d", result ? 1 : 0);
187+
}
188+
{
189+
int64_t result = remote_config::GetLong("TestLong");
190+
logMessage("Updated TestLong %lld", result);
191+
}
192+
{
193+
double result = remote_config::GetDouble("TestDouble");
194+
logMessage("Updated TestDouble %f", result);
195+
}
196+
{
197+
std::string result = remote_config::GetString("TestString");
198+
logMessage("Updated TestString %s", result.c_str());
199+
}
200+
{
201+
std::vector<unsigned char> result = remote_config::GetData("TestData");
202+
for (size_t i = 0; i < result.size(); ++i) {
203+
const unsigned char value = result[i];
204+
logMessage("TestData[%d] = 0x%02x", i, value);
205+
}
206+
}
207+
208+
// Print out the keys that are now tied to data
209+
std::vector keys = remote_config::GetKeys();
210+
logMessage("GetKeys:");
211+
for (auto s = keys.begin(); s != keys.end(); ++s) {
212+
logMessage(" %s", s->c_str());
213+
}
214+
keys = remote_config::GetKeysByPrefix("TestD");
215+
logMessage("GetKeysByPrefix(\"TestD\"):");
216+
for (auto s = keys.begin(); s != keys.end(); ++s) {
217+
logMessage(" %s", s->c_str());
218+
}
219+
220+
// Release a handle to the future so we can shutdown the Remote Config API
221+
// when exiting the app. Alternatively we could have placed future in a scope
222+
// different to our shutdown code below.
223+
future_.Release();
224+
}
225+
226+
/// Handles the user tapping on the close app menu item.
227+
void FirebaseRemoteConfigScene::menuCloseAppCallback(Ref* pSender) {
228+
CCLOG("Cleaning up Remote Config C++ resources.");
229+
firebase::remote_config::Terminate();
230+
231+
// Close the cocos2d-x game scene and quit the application.
232+
Director::getInstance()->end();
233+
234+
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
235+
exit(0);
236+
#endif
237+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2017 Google Inc. All rights reserved.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy
4+
// of this software and associated documentation files (the "Software"), to
5+
// deal in the Software without restriction, including without limitation the
6+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7+
// sell copies of the Software, and to permit persons to whom the Software is
8+
// furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in
11+
// all copies or substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16+
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
// SOFTWARE.
20+
21+
#ifndef FIREBASE_COCOS_CLASSES_FIREBASE_REMOTE_CONFIG_SCENE_H_
22+
#define FIREBASE_COCOS_CLASSES_FIREBASE_REMOTE_CONFIG_SCENE_H_
23+
24+
#include "cocos2d.h"
25+
#include "ui/CocosGUI.h"
26+
27+
#include "firebase/future.h"
28+
#include "FirebaseCocos.h"
29+
#include "FirebaseScene.h"
30+
31+
class FirebaseRemoteConfigScene : public FirebaseScene {
32+
public:
33+
static cocos2d::Scene *createScene();
34+
35+
bool init() override;
36+
37+
void update(float delta) override;
38+
39+
void menuCloseAppCallback(cocos2d::Ref *pSender) override;
40+
41+
CREATE_FUNC(FirebaseRemoteConfigScene);
42+
private:
43+
44+
// The future returned from calling remote_config::Fetch. The future created
45+
// then polled in the update loop until the data is returned.
46+
firebase::Future<void> future_;
47+
};
48+
49+
#endif // FIREBASE_COCOS_CLASSES_FIREBASE_REMOTE_CONFIG_SCENE_H_

remote_config/Podfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
source 'https://github.com/CocoaPods/Specs.git'
2+
3+
platform :ios, '7.0'
4+
5+
target 'HelloCpp-mobile' do
6+
pod 'Firebase/Core'
7+
pod 'Firebase/RemoteConfig'
8+
end

remote_config/app/build.gradle

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
apply plugin: 'com.android.application'
2+
3+
android {
4+
compileSdkVersion 22
5+
buildToolsVersion "22.0.1"
6+
7+
defaultConfig {
8+
applicationId "org.cocos2dx.hellocpp"
9+
minSdkVersion 10
10+
targetSdkVersion 22
11+
versionCode 1
12+
versionName "1.0"
13+
}
14+
15+
sourceSets.main {
16+
java.srcDir "src"
17+
res.srcDir "res"
18+
jniLibs.srcDir "libs"
19+
manifest.srcFile "AndroidManifest.xml"
20+
assets.srcDir "assets"
21+
}
22+
23+
signingConfigs {
24+
25+
release {
26+
if (project.hasProperty("RELEASE_STORE_FILE")) {
27+
storeFile file(RELEASE_STORE_FILE)
28+
storePassword RELEASE_STORE_PASSWORD
29+
keyAlias RELEASE_KEY_ALIAS
30+
keyPassword RELEASE_KEY_PASSWORD
31+
}
32+
}
33+
}
34+
35+
buildTypes {
36+
release {
37+
minifyEnabled false
38+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
39+
if (project.hasProperty("RELEASE_STORE_FILE")) {
40+
signingConfig signingConfigs.release
41+
}
42+
}
43+
}
44+
}
45+
46+
dependencies {
47+
compile fileTree(dir: 'libs', include: ['*.jar'])
48+
compile project(':libcocos2dx')
49+
compile 'com.google.firebase:firebase-config:10.0.1'
50+
compile 'com.google.android.gms:play-services-base:10.0.1'
51+
}
52+
53+
apply plugin: 'com.google.gms.google-services'
54+
55+
task cleanAssets(type: Delete) {
56+
delete 'assets'
57+
}
58+
task copyAssets(type: Copy) {
59+
from '../../Resources'
60+
into 'assets'
61+
}
62+
63+
clean.dependsOn cleanAssets
64+
preBuild.dependsOn copyAssets

remote_config/build.gradle

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
2+
3+
buildscript {
4+
repositories {
5+
jcenter()
6+
}
7+
dependencies {
8+
classpath 'com.android.tools.build:gradle:1.3.0'
9+
classpath 'com.google.gms:google-services:3.0.0'
10+
// NOTE: Do not place your application dependencies here; they belong
11+
// in the individual module build.gradle files
12+
}
13+
}
14+
15+
allprojects {
16+
repositories {
17+
jcenter()
18+
}
19+
}

0 commit comments

Comments
 (0)