├── .gitignore ├── common ├── Resources │ ├── NormalButtonImage.png │ └── SelectedButtonImage.png ├── project_template_files │ └── Android.mk └── Classes │ ├── FirebaseCocos.h │ ├── FirebaseScene.h │ └── FirebaseScene.cpp ├── admob ├── Podfile ├── build.gradle ├── app │ └── build.gradle └── Classes │ ├── FirebaseAdMobScene.h │ └── FirebaseAdMobScene.cpp ├── auth ├── Podfile ├── build.gradle ├── app │ └── build.gradle └── Classes │ ├── FirebaseAuthScene.h │ └── FirebaseAuthScene.cpp ├── invites ├── Podfile ├── build.gradle ├── app │ └── build.gradle └── Classes │ ├── FirebaseInvitesScene.h │ └── FirebaseInvitesScene.cpp ├── analytics ├── Podfile ├── build.gradle ├── app │ └── build.gradle └── Classes │ ├── FirebaseAnalyticsScene.h │ └── FirebaseAnalyticsScene.cpp ├── messaging ├── Podfile ├── build.gradle ├── Classes │ ├── FirebaseMessagingScene.h │ └── FirebaseMessagingScene.cpp └── app │ └── build.gradle ├── remote_config ├── Podfile ├── build.gradle ├── app │ └── build.gradle └── Classes │ ├── FirebaseRemoteConfigScene.h │ └── FirebaseRemoteConfigScene.cpp ├── storage ├── Podfile ├── build.gradle ├── app │ └── build.gradle ├── project_files │ └── Android.mk └── Classes │ ├── FirebaseStorageScene.h │ └── FirebaseStorageScene.cpp ├── database ├── Podfile ├── build.gradle ├── app │ └── build.gradle ├── project_files │ └── Android.mk └── Classes │ ├── FirebaseDatabaseScene.h │ └── FirebaseDatabaseScene.cpp ├── .github └── ISSUE_TEMPLATE │ └── config.yml ├── LICENSE ├── third_party └── cocos2dx │ ├── LICENSE │ └── common │ └── Classes │ ├── AppDelegate.h │ └── AppDelegate.cpp ├── README.md ├── CONTRIBUTING.md └── setup_firebase_sample.py /.gitignore: -------------------------------------------------------------------------------- 1 | sample_project/ 2 | -------------------------------------------------------------------------------- /common/Resources/NormalButtonImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FirebaseExtended/cocos2dx-cpp-sample/HEAD/common/Resources/NormalButtonImage.png -------------------------------------------------------------------------------- /common/Resources/SelectedButtonImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FirebaseExtended/cocos2dx-cpp-sample/HEAD/common/Resources/SelectedButtonImage.png -------------------------------------------------------------------------------- /admob/Podfile: -------------------------------------------------------------------------------- 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/AdMob' 8 | end 9 | -------------------------------------------------------------------------------- /auth/Podfile: -------------------------------------------------------------------------------- 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/Auth' 8 | end 9 | -------------------------------------------------------------------------------- /invites/Podfile: -------------------------------------------------------------------------------- 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/Invites' 8 | end 9 | -------------------------------------------------------------------------------- /analytics/Podfile: -------------------------------------------------------------------------------- 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/Analytics' 8 | end 9 | -------------------------------------------------------------------------------- /messaging/Podfile: -------------------------------------------------------------------------------- 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/Messaging' 8 | end 9 | -------------------------------------------------------------------------------- /remote_config/Podfile: -------------------------------------------------------------------------------- 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 9 | -------------------------------------------------------------------------------- /storage/Podfile: -------------------------------------------------------------------------------- 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/Auth' 8 | pod 'Firebase/Storage' 9 | end 10 | -------------------------------------------------------------------------------- /database/Podfile: -------------------------------------------------------------------------------- 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/Auth' 8 | pod 'Firebase/Database' 9 | end 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 🛑 Repository Archived 4 | url: https://firebase.google.com/docs/samples 5 | about: This repository is archived. Visit our samples page for a list of up-to-date samples. 6 | -------------------------------------------------------------------------------- /admob/build.gradle: -------------------------------------------------------------------------------- 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 | } 20 | -------------------------------------------------------------------------------- /auth/build.gradle: -------------------------------------------------------------------------------- 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 | } 20 | -------------------------------------------------------------------------------- /invites/build.gradle: -------------------------------------------------------------------------------- 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 | } 20 | -------------------------------------------------------------------------------- /storage/build.gradle: -------------------------------------------------------------------------------- 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 | } 20 | -------------------------------------------------------------------------------- /analytics/build.gradle: -------------------------------------------------------------------------------- 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 | } 20 | -------------------------------------------------------------------------------- /database/build.gradle: -------------------------------------------------------------------------------- 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 | } 20 | -------------------------------------------------------------------------------- /messaging/build.gradle: -------------------------------------------------------------------------------- 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 | } 20 | -------------------------------------------------------------------------------- /remote_config/build.gradle: -------------------------------------------------------------------------------- 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 | } 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 Google Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | 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, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 16 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 17 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /third_party/cocos2dx/LICENSE: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | Copyright (c) 2010 cocos2d-x.org 3 | http://www.cocos2d-x.org 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 18 | THE SOFTWARE. 19 | ****************************************************************************/ 20 | -------------------------------------------------------------------------------- /admob/app/build.gradle: -------------------------------------------------------------------------------- 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 14 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-ads:11.0.0' 50 | } 51 | 52 | apply plugin: 'com.google.gms.google-services' 53 | 54 | task cleanAssets(type: Delete) { 55 | delete 'assets' 56 | } 57 | task copyAssets(type: Copy) { 58 | from '../../Resources' 59 | into 'assets' 60 | } 61 | 62 | clean.dependsOn cleanAssets 63 | preBuild.dependsOn copyAssets 64 | -------------------------------------------------------------------------------- /auth/app/build.gradle: -------------------------------------------------------------------------------- 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 14 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-auth:11.0.0' 50 | compile 'com.google.android.gms:play-services-base:11.0.0' 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 65 | -------------------------------------------------------------------------------- /analytics/app/build.gradle: -------------------------------------------------------------------------------- 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 14 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-core:11.0.0' 50 | compile 'com.google.android.gms:play-services-base:11.0.0' 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 65 | -------------------------------------------------------------------------------- /invites/app/build.gradle: -------------------------------------------------------------------------------- 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 14 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-invites:11.0.0' 50 | compile 'com.google.android.gms:play-services-base:11.0.0' 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 65 | -------------------------------------------------------------------------------- /remote_config/app/build.gradle: -------------------------------------------------------------------------------- 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 14 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:11.0.0' 50 | compile 'com.google.android.gms:play-services-base:11.0.0' 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 65 | -------------------------------------------------------------------------------- /messaging/Classes/FirebaseMessagingScene.h: -------------------------------------------------------------------------------- 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_MESSAGING_SCENE_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_MESSAGING_SCENE_H_ 23 | 24 | #include "cocos2d.h" 25 | #include "ui/CocosGUI.h" 26 | 27 | #include "FirebaseCocos.h" 28 | #include "FirebaseScene.h" 29 | 30 | class FirebaseMessagingScene : public FirebaseScene { 31 | public: 32 | static cocos2d::Scene *createScene(); 33 | 34 | bool init() override; 35 | 36 | void update(float delta) override; 37 | 38 | void menuCloseAppCallback(cocos2d::Ref *pSender) override; 39 | 40 | CREATE_FUNC(FirebaseMessagingScene); 41 | }; 42 | 43 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_MESSAGING_SCENE_H_ 44 | -------------------------------------------------------------------------------- /database/app/build.gradle: -------------------------------------------------------------------------------- 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 14 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-auth:11.0.0' 50 | compile 'com.google.firebase:firebase-database:11.0.0' 51 | compile 'com.google.android.gms:play-services-base:11.0.0' 52 | } 53 | 54 | apply plugin: 'com.google.gms.google-services' 55 | 56 | task cleanAssets(type: Delete) { 57 | delete 'assets' 58 | } 59 | task copyAssets(type: Copy) { 60 | from '../../Resources' 61 | into 'assets' 62 | } 63 | 64 | clean.dependsOn cleanAssets 65 | preBuild.dependsOn copyAssets 66 | -------------------------------------------------------------------------------- /storage/app/build.gradle: -------------------------------------------------------------------------------- 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 14 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-auth:11.0.0' 50 | compile 'com.google.firebase:firebase-storage:11.0.0' 51 | compile 'com.google.android.gms:play-services-base:11.0.0' 52 | } 53 | 54 | apply plugin: 'com.google.gms.google-services' 55 | 56 | task cleanAssets(type: Delete) { 57 | delete 'assets' 58 | } 59 | task copyAssets(type: Copy) { 60 | from '../../Resources' 61 | into 'assets' 62 | } 63 | 64 | clean.dependsOn cleanAssets 65 | preBuild.dependsOn copyAssets 66 | -------------------------------------------------------------------------------- /common/project_template_files/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | APP_ABI := armeabi-v7a x86 arm64 4 | 5 | STL := $(firstword $(subst _, ,$(APP_STL))) 6 | FIREBASE_CPP_SDK_DIR := ../../../Libs/firebase_cpp_sdk 7 | FIREBASE_LIBRARY_PATH := $(FIREBASE_CPP_SDK_DIR)/libs/android/$(TARGET_ARCH_ABI)/$(STL) 8 | 9 | include $(CLEAR_VARS) 10 | LOCAL_MODULE := firebase_app 11 | LOCAL_SRC_FILES := $(FIREBASE_LIBRARY_PATH)/libapp.a 12 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(FIREBASE_CPP_SDK_DIR)/include 13 | include $(PREBUILT_STATIC_LIBRARY) 14 | 15 | include $(CLEAR_VARS) 16 | LOCAL_MODULE := firebase_feature 17 | LOCAL_SRC_FILES := $(FIREBASE_LIBRARY_PATH)/lib{FIREBASE_FEATURE}.a 18 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(FIREBASE_CPP_SDK_DIR)/include 19 | include $(PREBUILT_STATIC_LIBRARY) 20 | 21 | include $(CLEAR_VARS) 22 | 23 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d) 24 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/external) 25 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/cocos) 26 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/cocos/audio/include) 27 | 28 | LOCAL_MODULE := MyGame_shared 29 | 30 | LOCAL_MODULE_FILENAME := libMyGame 31 | 32 | LOCAL_SRC_FILES := hellocpp/main.cpp \ 33 | ../../../Classes/AppDelegate.cpp \ 34 | ../../../Classes/FirebaseScene.cpp \ 35 | ../../../Classes/Firebase{FIREBASE_FEATURE_CAMELCASE}Scene.cpp \ 36 | 37 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes 38 | 39 | # _COCOS_HEADER_ANDROID_BEGIN 40 | # _COCOS_HEADER_ANDROID_END 41 | 42 | LOCAL_STATIC_LIBRARIES := cocos2dx_static 43 | LOCAL_STATIC_LIBRARIES += firebase_app 44 | LOCAL_STATIC_LIBRARIES += firebase_feature 45 | 46 | # _COCOS_LIB_ANDROID_BEGIN 47 | # _COCOS_LIB_ANDROID_END 48 | 49 | include $(BUILD_SHARED_LIBRARY) 50 | 51 | $(call import-module,.) 52 | 53 | # _COCOS_LIB_IMPORT_ANDROID_BEGIN 54 | # _COCOS_LIB_IMPORT_ANDROID_END 55 | 56 | -------------------------------------------------------------------------------- /messaging/app/build.gradle: -------------------------------------------------------------------------------- 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 14 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 | repositories { 47 | flatDir{ 48 | dirs 'libs/android', '../../Libs/firebase_cpp_sdk/libs/android' 49 | } 50 | } 51 | 52 | dependencies { 53 | compile fileTree(dir: 'libs', include: ['*.jar']) 54 | compile project(':libcocos2dx') 55 | compile 'com.google.firebase.messaging.cpp:firebase_messaging_cpp@aar' 56 | compile 'com.google.firebase:firebase-messaging:11.0.0' 57 | compile 'com.google.android.gms:play-services-base:11.0.0' 58 | } 59 | 60 | apply plugin: 'com.google.gms.google-services' 61 | 62 | task cleanAssets(type: Delete) { 63 | delete 'assets' 64 | } 65 | task copyAssets(type: Copy) { 66 | from '../../Resources' 67 | into 'assets' 68 | } 69 | 70 | clean.dependsOn cleanAssets 71 | preBuild.dependsOn copyAssets 72 | -------------------------------------------------------------------------------- /invites/Classes/FirebaseInvitesScene.h: -------------------------------------------------------------------------------- 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_INVITES_SCENE_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_INVITES_SCENE_H_ 23 | 24 | #include "cocos2d.h" 25 | #include "ui/CocosGUI.h" 26 | 27 | #include "FirebaseCocos.h" 28 | #include "FirebaseScene.h" 29 | 30 | class FirebaseInvitesScene : public FirebaseScene { 31 | public: 32 | FirebaseInvitesScene() : invite_button_(nullptr), invite_sent_(false) {} 33 | 34 | static cocos2d::Scene *createScene(); 35 | 36 | bool init() override; 37 | 38 | void update(float delta) override; 39 | 40 | void menuCloseAppCallback(cocos2d::Ref *pSender) override; 41 | 42 | CREATE_FUNC(FirebaseInvitesScene); 43 | 44 | private: 45 | /// The button for loading an ad view. 46 | cocos2d::ui::Button* invite_button_; 47 | 48 | /// Keep track of whether an invite has been sent. 49 | bool invite_sent_; 50 | }; 51 | 52 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_INVITES_SCENE_H_ 53 | -------------------------------------------------------------------------------- /remote_config/Classes/FirebaseRemoteConfigScene.h: -------------------------------------------------------------------------------- 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 future_; 47 | }; 48 | 49 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_REMOTE_CONFIG_SCENE_H_ 50 | -------------------------------------------------------------------------------- /storage/project_files/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | APP_ABI := armeabi-v7a x86 arm64 4 | 5 | STL := $(firstword $(subst _, ,$(APP_STL))) 6 | FIREBASE_CPP_SDK_DIR := ../../../Libs/firebase_cpp_sdk 7 | FIREBASE_LIBRARY_PATH := $(FIREBASE_CPP_SDK_DIR)/libs/android/$(TARGET_ARCH_ABI)/$(STL) 8 | 9 | include $(CLEAR_VARS) 10 | LOCAL_MODULE := firebase_app 11 | LOCAL_SRC_FILES := $(FIREBASE_LIBRARY_PATH)/libapp.a 12 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(FIREBASE_CPP_SDK_DIR)/include 13 | include $(PREBUILT_STATIC_LIBRARY) 14 | 15 | include $(CLEAR_VARS) 16 | LOCAL_MODULE := firebase_auth 17 | LOCAL_SRC_FILES := $(FIREBASE_LIBRARY_PATH)/libauth.a 18 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(FIREBASE_CPP_SDK_DIR)/include 19 | include $(PREBUILT_STATIC_LIBRARY) 20 | 21 | include $(CLEAR_VARS) 22 | LOCAL_MODULE := firebase_storage 23 | LOCAL_SRC_FILES := $(FIREBASE_LIBRARY_PATH)/libstorage.a 24 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(FIREBASE_CPP_SDK_DIR)/include 25 | include $(PREBUILT_STATIC_LIBRARY) 26 | 27 | include $(CLEAR_VARS) 28 | 29 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d) 30 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/external) 31 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/cocos) 32 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/cocos/audio/include) 33 | 34 | LOCAL_MODULE := MyGame_shared 35 | 36 | LOCAL_MODULE_FILENAME := libMyGame 37 | 38 | LOCAL_SRC_FILES := hellocpp/main.cpp \ 39 | ../../../Classes/AppDelegate.cpp \ 40 | ../../../Classes/FirebaseScene.cpp \ 41 | ../../../Classes/FirebaseStorageScene.cpp \ 42 | 43 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes 44 | 45 | # _COCOS_HEADER_ANDROID_BEGIN 46 | # _COCOS_HEADER_ANDROID_END 47 | 48 | LOCAL_STATIC_LIBRARIES := cocos2dx_static 49 | LOCAL_STATIC_LIBRARIES += firebase_storage 50 | LOCAL_STATIC_LIBRARIES += firebase_auth 51 | LOCAL_STATIC_LIBRARIES += firebase_app 52 | 53 | # _COCOS_LIB_ANDROID_BEGIN 54 | # _COCOS_LIB_ANDROID_END 55 | 56 | include $(BUILD_SHARED_LIBRARY) 57 | 58 | $(call import-module,.) 59 | 60 | # _COCOS_LIB_IMPORT_ANDROID_BEGIN 61 | # _COCOS_LIB_IMPORT_ANDROID_END 62 | -------------------------------------------------------------------------------- /database/project_files/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | APP_ABI := armeabi-v7a x86 arm64 4 | 5 | STL := $(firstword $(subst _, ,$(APP_STL))) 6 | FIREBASE_CPP_SDK_DIR := ../../../Libs/firebase_cpp_sdk 7 | FIREBASE_LIBRARY_PATH := $(FIREBASE_CPP_SDK_DIR)/libs/android/$(TARGET_ARCH_ABI)/$(STL) 8 | 9 | include $(CLEAR_VARS) 10 | LOCAL_MODULE := firebase_app 11 | LOCAL_SRC_FILES := $(FIREBASE_LIBRARY_PATH)/libapp.a 12 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(FIREBASE_CPP_SDK_DIR)/include 13 | include $(PREBUILT_STATIC_LIBRARY) 14 | 15 | include $(CLEAR_VARS) 16 | LOCAL_MODULE := firebase_auth 17 | LOCAL_SRC_FILES := $(FIREBASE_LIBRARY_PATH)/libauth.a 18 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(FIREBASE_CPP_SDK_DIR)/include 19 | include $(PREBUILT_STATIC_LIBRARY) 20 | 21 | include $(CLEAR_VARS) 22 | LOCAL_MODULE := firebase_database 23 | LOCAL_SRC_FILES := $(FIREBASE_LIBRARY_PATH)/libdatabase.a 24 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(FIREBASE_CPP_SDK_DIR)/include 25 | include $(PREBUILT_STATIC_LIBRARY) 26 | 27 | include $(CLEAR_VARS) 28 | 29 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d) 30 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/external) 31 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/cocos) 32 | $(call import-add-path,$(LOCAL_PATH)/../../../cocos2d/cocos/audio/include) 33 | 34 | LOCAL_MODULE := MyGame_shared 35 | 36 | LOCAL_MODULE_FILENAME := libMyGame 37 | 38 | LOCAL_SRC_FILES := hellocpp/main.cpp \ 39 | ../../../Classes/AppDelegate.cpp \ 40 | ../../../Classes/FirebaseScene.cpp \ 41 | ../../../Classes/FirebaseDatabaseScene.cpp \ 42 | 43 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes 44 | 45 | # _COCOS_HEADER_ANDROID_BEGIN 46 | # _COCOS_HEADER_ANDROID_END 47 | 48 | LOCAL_STATIC_LIBRARIES := cocos2dx_static 49 | LOCAL_STATIC_LIBRARIES += firebase_database 50 | LOCAL_STATIC_LIBRARIES += firebase_auth 51 | LOCAL_STATIC_LIBRARIES += firebase_app 52 | 53 | # _COCOS_LIB_ANDROID_BEGIN 54 | # _COCOS_LIB_ANDROID_END 55 | 56 | include $(BUILD_SHARED_LIBRARY) 57 | 58 | $(call import-module,.) 59 | 60 | # _COCOS_LIB_IMPORT_ANDROID_BEGIN 61 | # _COCOS_LIB_IMPORT_ANDROID_END 62 | -------------------------------------------------------------------------------- /common/Classes/FirebaseCocos.h: -------------------------------------------------------------------------------- 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_COCOS_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_COCOS_H_ 23 | 24 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 25 | #include 26 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 27 | extern "C" { 28 | #include 29 | } // extern "C" 30 | #endif 31 | 32 | // WindowContext represents the handle to the parent window. It's type 33 | // (and usage) vary based on the OS. 34 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 35 | typedef jobject WindowContext; // A jobject to the Java Activity. 36 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 37 | typedef id WindowContext; // A pointer to an iOS UIView. 38 | #else 39 | typedef void* WindowContext; // A void* for any other environments. 40 | #endif 41 | 42 | // Returns a variable that describes the window context for the app. On Android 43 | // this will be a jobject pointing to the Activity. On iOS, it's an id pointing 44 | // to the root view of the view controller. 45 | WindowContext getWindowContext(); 46 | 47 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_COCOS_H_ 48 | -------------------------------------------------------------------------------- /third_party/cocos2dx/common/Classes/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | Copyright (c) 2013 cocos2d-x.org 3 | Copyright (c) 2013-2014 Chukong Technologies Inc. 4 | 5 | http://www.cocos2d-x.org 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | ****************************************************************************/ 25 | 26 | #ifndef _APP_DELEGATE_H_ 27 | #define _APP_DELEGATE_H_ 28 | 29 | #include "cocos2d.h" 30 | 31 | /** 32 | @brief The cocos2d Application. 33 | 34 | Private inheritance here hides part of interface from Director. 35 | */ 36 | class AppDelegate : private cocos2d::Application { 37 | public: 38 | AppDelegate(); 39 | virtual ~AppDelegate(); 40 | 41 | virtual void initGLContextAttrs(); 42 | 43 | /** 44 | @brief Implement Director and Scene init code here. 45 | @return true Initialize success, app continue. 46 | @return false Initialize failed, app terminate. 47 | */ 48 | virtual bool applicationDidFinishLaunching(); 49 | 50 | /** 51 | @brief Called when the application moves to the background 52 | @param the pointer of the application 53 | */ 54 | virtual void applicationDidEnterBackground(); 55 | 56 | /** 57 | @brief Called when the application reenters the foreground 58 | @param the pointer of the application 59 | */ 60 | virtual void applicationWillEnterForeground(); 61 | }; 62 | 63 | #endif // _APP_DELEGATE_H_ 64 | -------------------------------------------------------------------------------- /auth/Classes/FirebaseAuthScene.h: -------------------------------------------------------------------------------- 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_AUTH_SCENE_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_AUTH_SCENE_H_ 23 | 24 | #include "cocos2d.h" 25 | #include "ui/CocosGUI.h" 26 | 27 | #include "FirebaseCocos.h" 28 | #include "FirebaseScene.h" 29 | #include "firebase/auth.h" 30 | #include "firebase/future.h" 31 | 32 | class FirebaseAuthScene : public FirebaseScene { 33 | public: 34 | static cocos2d::Scene *createScene(); 35 | 36 | bool init() override; 37 | 38 | void update(float delta) override; 39 | 40 | void menuCloseAppCallback(cocos2d::Ref *pSender) override; 41 | 42 | CREATE_FUNC(FirebaseAuthScene); 43 | private: 44 | /// A text field where a login email address may be entered. 45 | cocos2d::ui::TextField* email_text_field_; 46 | 47 | /// A text field where a login password may be entered. 48 | cocos2d::ui::TextField* password_text_field_; 49 | 50 | /// A button that uses the given email and password to register a user. 51 | cocos2d::ui::Button* register_user_button_; 52 | 53 | /// A button that uses the given email and password to log in. 54 | cocos2d::ui::Button* credentialed_sign_in_button_; 55 | 56 | /// A button that logs in anonymously. 57 | cocos2d::ui::Button* anonymous_sign_in_button_; 58 | 59 | /// A button that logs the user out regardless of how they logged in. 60 | cocos2d::ui::Button* sign_out_button_; 61 | 62 | /// A future that completes some time after attempting to create a new user. 63 | firebase::Future create_user_future_; 64 | 65 | /// A future that completes some time after one of the login buttons is 66 | /// pressed. 67 | firebase::Future sign_in_future_; 68 | 69 | /// Keeps track of whether or not the sign in attempt was made anonymously. 70 | bool anonymous_sign_in_; 71 | }; 72 | 73 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_AUTH_SCENE_H_ 74 | -------------------------------------------------------------------------------- /analytics/Classes/FirebaseAnalyticsScene.h: -------------------------------------------------------------------------------- 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_ANALYTICS_SCENE_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_ANALYTICS_SCENE_H_ 23 | 24 | #include "cocos2d.h" 25 | #include "ui/CocosGUI.h" 26 | 27 | #include "FirebaseCocos.h" 28 | #include "FirebaseScene.h" 29 | 30 | class FirebaseAnalyticsScene : public FirebaseScene { 31 | public: 32 | static cocos2d::Scene *createScene(); 33 | 34 | FirebaseAnalyticsScene() : 35 | blue_button_click_count_(0), 36 | total_button_click_count_(0), 37 | previous_button_clicked_("None"), 38 | green_button_click_count_(0) {} 39 | 40 | bool init() override; 41 | 42 | void update(float delta) override; 43 | 44 | void menuCloseAppCallback(cocos2d::Ref *pSender) override; 45 | 46 | CREATE_FUNC(FirebaseAnalyticsScene); 47 | 48 | private: 49 | /// A blue button that records how many times it has been clicked. 50 | cocos2d::ui::Button* blue_button_; 51 | 52 | /// A red button that records how many times any button has been clicked. 53 | cocos2d::ui::Button* red_button_; 54 | 55 | /// A yellow button that records what button was clicked previously. 56 | cocos2d::ui::Button* yellow_button_; 57 | 58 | /// A green button that records what ratio of button clicks were green. 59 | cocos2d::ui::Button* green_button_; 60 | 61 | // The following are some arbitrary statistics to collect to demonstrate how 62 | // they can be reported to Firebase Analytics. 63 | 64 | /// The total number of times the blue button has been clicked. 65 | int blue_button_click_count_; 66 | 67 | /// The total number of times any button has been clicked. 68 | int total_button_click_count_; 69 | 70 | /// The button that was clicked previously. 71 | const char* previous_button_clicked_; 72 | 73 | /// What fraction of the clicks were made on the green button. 74 | int green_button_click_count_; 75 | }; 76 | 77 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_ANALYTICS_SCENE_H_ 78 | -------------------------------------------------------------------------------- /common/Classes/FirebaseScene.h: -------------------------------------------------------------------------------- 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_SCENE_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_SCENE_H_ 23 | 24 | #include "cocos2d.h" 25 | #include "ui/CocosGUI.h" 26 | 27 | #include "FirebaseCocos.h" 28 | 29 | /// This factory method creates a FirebaseScene. The implementation is provided 30 | /// by each sample project so that it will always return the FirebaseScene 31 | /// associated with that sample. 32 | cocos2d::Scene* CreateFirebaseScene(); 33 | 34 | class FirebaseScene : public cocos2d::Layer { 35 | public: 36 | /// Initialize the scene. This must be called before the scene can be 37 | /// interacted with or updated. 38 | /// 39 | /// @return True if the scene was initialized successfully. 40 | virtual bool init() = 0; 41 | 42 | /// Update the scene. This is run once per frame. 43 | /// 44 | /// @param delta The number of seconds since the last update. 45 | virtual void update(float delta) = 0; 46 | 47 | /// Called just before the app closes. This is where cleanup and shutdown 48 | /// logic should go. 49 | virtual void menuCloseAppCallback(cocos2d::Ref* pSender) = 0; 50 | 51 | /// Updates the log text in the Firebase scene's TextWidget. 52 | void logMessage(std::string format, ...); 53 | 54 | protected: 55 | /// The Y position for a UI element. 56 | float nextYPosition; 57 | 58 | /// Creates a button for interacting with Firebase. 59 | cocos2d::ui::Button *createButton( 60 | bool buttonEnabled, const std::string& buttonTitleText, 61 | const cocos2d::Color3B& buttonColor); 62 | 63 | /// Creates a button for interacting with Firebase. 64 | cocos2d::ui::Button *createButton( 65 | bool buttonEnabled, const std::string& buttonTitleText); 66 | 67 | /// Creates a single line text entry field. 68 | cocos2d::ui::TextField *createTextField(const char* placeholder); 69 | 70 | /// Creates the ScrollView that contains a TextWidget for displaying log text 71 | /// to the user. 72 | /// 73 | /// By default the it will be half the width of the parent widget, but that 74 | /// can be adjusted by supplying a width argument. 75 | void createScrollView(float yPosition); 76 | void createScrollView(float yPosition, float widthFraction); 77 | }; 78 | 79 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_SCENE_H_ 80 | -------------------------------------------------------------------------------- /admob/Classes/FirebaseAdMobScene.h: -------------------------------------------------------------------------------- 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_ADMOB_SCENE_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_ADMOB_SCENE_H_ 23 | 24 | #include "cocos2d.h" 25 | #include "ui/CocosGUI.h" 26 | 27 | #include "FirebaseCocos.h" 28 | #include "FirebaseScene.h" 29 | 30 | #include "firebase/admob.h" 31 | #include "firebase/admob/banner_view.h" 32 | #include "firebase/admob/interstitial_ad.h" 33 | #include "firebase/admob/rewarded_video.h" 34 | #include "firebase/admob/types.h" 35 | #include "firebase/app.h" 36 | #include "firebase/future.h" 37 | 38 | class LoggingAdViewListener; 39 | class LoggingInterstitialAdListener; 40 | class LoggingRewardedVideoListener; 41 | 42 | class FirebaseAdMobScene : public FirebaseScene { 43 | public: 44 | static cocos2d::Scene *createScene(); 45 | 46 | bool init() override; 47 | 48 | void update(float delta) override; 49 | 50 | void menuCloseAppCallback(cocos2d::Ref *pSender) override; 51 | 52 | CREATE_FUNC(FirebaseAdMobScene); 53 | 54 | private: 55 | /// The AdMob ad view C++ object. 56 | firebase::admob::BannerView* adView; 57 | 58 | /// The AdMob InterstitialAd C++ object. 59 | firebase::admob::InterstitialAd* interstitialAd; 60 | 61 | /// The button for loading an ad view. 62 | cocos2d::ui::Button* loadAdViewBtn; 63 | 64 | /// The button for showing and hiding the ad view. 65 | cocos2d::ui::Button* showHideAdViewBtn; 66 | 67 | /// The button for moving the ad view. 68 | cocos2d::ui::Button* moveAdViewBtn; 69 | 70 | /// The button for loading an InterstitialAd. 71 | cocos2d::ui::Button* loadInterstitialAdBtn; 72 | 73 | /// The button for showing the InterstitialAd. 74 | cocos2d::ui::Button* showInterstitialAdBtn; 75 | 76 | /// The button for loading a rewarded video. 77 | cocos2d::ui::Button* loadRewardedVideoBtn; 78 | 79 | /// The button for showing the rewarded video. 80 | cocos2d::ui::Button* showRewardedVideoBtn; 81 | 82 | /// The ad view listener. 83 | LoggingAdViewListener* adViewListener; 84 | 85 | /// The admob::InterstitialAd listener. 86 | LoggingInterstitialAdListener* interstitialAdListener; 87 | 88 | /// The admob::rewarded_video listener. 89 | LoggingRewardedVideoListener* rewardedVideoListener; 90 | 91 | /// Returns an AdMob AdRequest. 92 | firebase::admob::AdRequest createAdRequest(); 93 | }; 94 | 95 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_ADMOB_SCENE_H_ 96 | -------------------------------------------------------------------------------- /database/Classes/FirebaseDatabaseScene.h: -------------------------------------------------------------------------------- 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_DATABASE_SCENE_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_DATABASE_SCENE_H_ 23 | 24 | #include "cocos2d.h" 25 | #include "ui/CocosGUI.h" 26 | 27 | #include "FirebaseCocos.h" 28 | #include "FirebaseScene.h" 29 | #include "firebase/auth.h" 30 | #include "firebase/database.h" 31 | #include "firebase/future.h" 32 | #include "firebase/util.h" 33 | 34 | class FirebaseDatabaseScene : public FirebaseScene { 35 | public: 36 | static cocos2d::Scene *createScene(); 37 | 38 | bool init() override; 39 | 40 | void update(float delta) override; 41 | 42 | void menuCloseAppCallback(cocos2d::Ref *pSender) override; 43 | 44 | CREATE_FUNC(FirebaseDatabaseScene); 45 | 46 | private: 47 | /// An enum that tracks what the operations the app should be keeping track 48 | /// of. First the app initializes the library, then it logs in using Firebase 49 | /// Authentication, and then it listens for reads or writes to the database. 50 | enum State { 51 | kStateInitialize, 52 | kStateLogin, 53 | kStateRun, 54 | }; 55 | 56 | /// The update loop to run while initializing the app. 57 | State updateInitialize(); 58 | 59 | /// The update loop to run while logging in. 60 | State updateLogin(); 61 | 62 | /// The update loop to run once all setup is complete. 63 | State updateRun(); 64 | 65 | /// Tracks the current state of the app through its setup and main loop. 66 | State state_; 67 | 68 | /// The ModuleInitializer is a utility class to make initializing multiple 69 | /// Firebase libraries easier. 70 | firebase::ModuleInitializer initializer_; 71 | 72 | /// Firebase Auth, used for logging into Firebase. 73 | firebase::auth::Auth* auth_; 74 | 75 | /// Firebase Realtime Database, the entry point to all database operations. 76 | firebase::database::Database* database_; 77 | 78 | /// A future that completes when the DataSnapshot for a query is received. 79 | firebase::Future query_future_; 80 | 81 | /// A future that completes when a databse write is complete. 82 | firebase::Future set_future_; 83 | 84 | /// A text field where a database key string may be entered. 85 | cocos2d::ui::TextField* key_text_field_; 86 | 87 | /// A text field where a database value string may be entered. 88 | cocos2d::ui::TextField* value_text_field_; 89 | 90 | /// A button that sets a listener on the node given by the key text field. 91 | cocos2d::ui::Button* add_listener_button_; 92 | 93 | /// A button that queries the value given by the key text field. 94 | cocos2d::ui::Button* query_button_; 95 | 96 | /// A button that sets the key to the value, given by the text fields. 97 | cocos2d::ui::Button* set_button_; 98 | }; 99 | 100 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_DATABASE_SCENE_H_ 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Firebase Cocos2d-x Samples 2 | ========================== 3 | 4 | iOS and Android cocos2d-x samples for the Firebase C++ SDK. 5 | 6 | ## Status 7 | 8 | ![Status: Archived](https://img.shields.io/badge/Status-Archived-red) 9 | 10 | This sample is no longer actively maintained and is left here for reference only. 11 | 12 | 13 | Introduction 14 | ------------ 15 | 16 | - [Read more about Firebase](https://firebase.google.com/docs) 17 | 18 | Prerequisites 19 | ------------- 20 | 21 | - The `setup_firebase_sample.py` script requires Python to be installed locally. 22 | Visit the [Python download page](https://www.python.org/downloads/) 23 | for more information. 24 | 25 | - If you are running this script on a Mac, you will need CocoaPods installed. 26 | See the CocoaPods [Getting Started guide](https://guides.cocoapods.org/using/getting-started.html) 27 | for more details. 28 | 29 | Getting Started 30 | --------------- 31 | 32 | - Clone the Firebase Cocos2d-x Samples GitHub repo. 33 | ``` 34 | git clone https://github.com/firebase/cocos2dx-cpp-sample.git 35 | ``` 36 | - Navigate to the directory that you just cloned and run the Firebase setup 37 | script, where FIREBASE_FEATURE is one of the following: 38 | AdMob, Analytics, Auth, Invites, Messaging, Remote_Config 39 | ``` 40 | python setup_firebase_sample.py FIREBASE_FEATURE 41 | ``` 42 | - If you haven't done so already, you will need to add the cocos2d-x environment 43 | variables to the operating system's PATH variable. Navigate to the 44 | `sample_project/cocos2d` directory and run the cocos2d-x setup script: 45 | ``` 46 | python setup.py 47 | ``` 48 | 49 | ### iOS 50 | - Follow the steps in 51 | [Set up your app in Firebase console](https://firebase.google.com/docs/cpp/setup#set_up_your_app_in_name_appmanager). 52 | - Bundle ID: org.cocos2dx.hellocpp 53 | - Open the `sample_project/proj.ios_mac/HelloCpp.xcworkspace` with Xcode. From 54 | the Project Navigator, right click on `HelloCpp` and select “Add files to 55 | HelloCpp.” Find the `GoogleService-Info.plist` file that you downloaded in 56 | step 1 and click the Add button. 57 | - In the top left corner, set the active scheme to HelloCpp-mobile and choose 58 | the device that you want to run the app on. Then, click the run button to 59 | build and run the app. 60 | 61 | ### Android 62 | - Follow the steps in 63 | [Set up your app in Firebase console](https://firebase.google.com/docs/cpp/setup#set_up_your_app_in_name_appmanager_1). 64 | - Package Name: org.cocos2dx.hellocpp 65 | - Add the google-services.json file that you downloaded in step 1 to the 66 | `sample_project/proj.android-studio/app` directory. 67 | - In the terminal from the `sample_project` directory, compile the Cocos project 68 | for Android: 69 | ``` 70 | cocos compile -p android --ap ## --android-studio --app-abi armeabi-v7a 71 | ``` 72 | Where `##` is the Android platform used for building the apk, 73 | for example, `android-22`. 74 | - Open the `sample_project/proj.android-studio` project in Android Studio and 75 | run the app. To install the APK on a device, navigate to 76 | `sample_project/bin/debug/android`. 77 | 78 | Support 79 | ------- 80 | 81 | https://firebase.google.com/support/ 82 | 83 | License 84 | ------- 85 | 86 | Copyright 2017 Google Inc. All rights reserved. 87 | 88 | Permission is hereby granted, free of charge, to any person obtaining a copy of 89 | this software and associated documentation files (the "Software"), to deal in 90 | the Software without restriction, including without limitation the rights to 91 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 92 | the Software, and to permit persons to whom the Software is furnished to do so, 93 | subject to the following conditions: 94 | 95 | The above copyright notice and this permission notice shall be included in all 96 | copies or substantial portions of the Software. 97 | 98 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 99 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 100 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 101 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 102 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 103 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 104 | -------------------------------------------------------------------------------- /storage/Classes/FirebaseStorageScene.h: -------------------------------------------------------------------------------- 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_STORAGE_SCENE_H_ 22 | #define FIREBASE_COCOS_CLASSES_FIREBASE_STORAGE_SCENE_H_ 23 | 24 | #include "cocos2d.h" 25 | #include "ui/CocosGUI.h" 26 | 27 | #include "FirebaseCocos.h" 28 | #include "FirebaseScene.h" 29 | #include "firebase/auth.h" 30 | #include "firebase/storage.h" 31 | #include "firebase/future.h" 32 | #include "firebase/util.h" 33 | 34 | // The size of the byte buffer that data will be written to. 35 | static const size_t kBufferSize = 1024; 36 | 37 | class StorageListener : public firebase::storage::Listener { 38 | public: 39 | virtual ~StorageListener() {} 40 | 41 | /// Called whenever a transferred is paused. 42 | void OnPaused(firebase::storage::Controller* controller) override; 43 | 44 | /// Called repeatedly as a transfer is in progress. 45 | void OnProgress(firebase::storage::Controller* controller) override; 46 | 47 | void set_scene(FirebaseScene* scene) { scene_ = scene; } 48 | 49 | private: 50 | FirebaseScene* scene_; 51 | }; 52 | 53 | class FirebaseStorageScene : public FirebaseScene { 54 | public: 55 | static cocos2d::Scene *createScene(); 56 | 57 | bool init() override; 58 | 59 | void update(float delta) override; 60 | 61 | void menuCloseAppCallback(cocos2d::Ref *pSender) override; 62 | 63 | CREATE_FUNC(FirebaseStorageScene); 64 | 65 | private: 66 | /// An enum that tracks what the operations the app should be keeping track 67 | /// of. First the app initializes the library, then it logs in using Firebase 68 | /// Authentication, and then it listens for reads or writes to the storage. 69 | enum State { 70 | kStateInitialize, 71 | kStateLogin, 72 | kStateRun, 73 | }; 74 | 75 | /// The update loop to run while initializing the app. 76 | State updateInitialize(); 77 | 78 | /// The update loop to run while logging in. 79 | State updateLogin(); 80 | 81 | /// The update loop to run once all setup is complete. 82 | State updateRun(); 83 | 84 | /// Tracks the current state of the app through its setup and main loop. 85 | State state_; 86 | 87 | /// The ModuleInitializer is a utility class to make initializing multiple 88 | /// Firebase libraries easier. 89 | firebase::ModuleInitializer initializer_; 90 | 91 | /// Firebase Auth, used for logging into Firebase. 92 | firebase::auth::Auth* auth_; 93 | 94 | /// Firebase Storage, the entry point to all storage operations. 95 | firebase::storage::Storage* storage_; 96 | 97 | /// A byte buffer for Firebase Storage to write to. 98 | char byte_buffer_[kBufferSize]; 99 | 100 | /// A listener that responds to PutBytes and GetBytes progress. 101 | StorageListener listener_; 102 | 103 | /// A future that completes when the DataSnapshot for a query is received. 104 | firebase::Future get_bytes_future_; 105 | 106 | /// A future that completes when a databse write is complete. 107 | firebase::Future put_bytes_future_; 108 | 109 | /// A text field where a storage key string may be entered. 110 | cocos2d::ui::TextField* key_text_field_; 111 | 112 | /// A text field where a storage value string may be entered. 113 | cocos2d::ui::TextField* value_text_field_; 114 | 115 | /// A button that queries the value given by the key text field. 116 | cocos2d::ui::Button* get_bytes_button_; 117 | 118 | /// A button that sets the key to the value, given by the text fields. 119 | cocos2d::ui::Button* put_bytes_button_; 120 | }; 121 | 122 | #endif // FIREBASE_COCOS_CLASSES_FIREBASE_STORAGE_SCENE_H_ 123 | -------------------------------------------------------------------------------- /third_party/cocos2dx/common/Classes/AppDelegate.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | Copyright (c) 2013 cocos2d-x.org 3 | Copyright (c) 2013-2014 Chukong Technologies Inc. 4 | 5 | http://www.cocos2d-x.org 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | ****************************************************************************/ 25 | 26 | #include "AppDelegate.h" 27 | 28 | #include "FirebaseScene.h" 29 | 30 | #include "firebase/app.h" 31 | 32 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 33 | #include 34 | #include "platform/android/jni/JniHelper.h" 35 | #endif 36 | 37 | USING_NS_CC; 38 | 39 | static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320); 40 | static cocos2d::Size smallResolutionSize = cocos2d::Size(480, 320); 41 | static cocos2d::Size mediumResolutionSize = cocos2d::Size(1024, 768); 42 | static cocos2d::Size largeResolutionSize = cocos2d::Size(2048, 1536); 43 | 44 | AppDelegate::AppDelegate() {} 45 | 46 | AppDelegate::~AppDelegate() {} 47 | 48 | // If you want a different context, modify the value of glContextAttrs. 49 | // It will affect all platforms 50 | void AppDelegate::initGLContextAttrs() { 51 | // Set OpenGL context attributes: red,green,blue,alpha,depth,stencil 52 | GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8}; 53 | 54 | GLView::setGLContextAttrs(glContextAttrs); 55 | } 56 | 57 | // If you want to use the package manager to install more packages, 58 | // Don't modify or remove this function 59 | static int register_all_packages() { 60 | return 0; // flag for packages manager 61 | } 62 | 63 | bool AppDelegate::applicationDidFinishLaunching() { 64 | // Initialize the director. 65 | auto director = Director::getInstance(); 66 | auto glview = director->getOpenGLView(); 67 | if (!glview) { 68 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || \ 69 | (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || \ 70 | (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) 71 | glview = GLViewImpl::createWithRect( 72 | "FirebaseCocos", cocos2d::Rect(0, 0, designResolutionSize.width, 73 | designResolutionSize.height)); 74 | #else 75 | glview = GLViewImpl::create("FirebaseCocos"); 76 | #endif 77 | director->setOpenGLView(glview); 78 | } 79 | 80 | // Turn on display FPS. 81 | director->setDisplayStats(false); 82 | 83 | // Set FPS. The default value is 1.0 / 60 if this is not called. 84 | director->setAnimationInterval(1.0f / 60); 85 | 86 | // Set the design resolution. 87 | glview->setDesignResolutionSize(designResolutionSize.width, 88 | designResolutionSize.height, 89 | ResolutionPolicy::NO_BORDER); 90 | auto frameSize = glview->getFrameSize(); 91 | // If the frame's height is larger than the height of medium size. 92 | if (frameSize.height > mediumResolutionSize.height) { 93 | director->setContentScaleFactor( 94 | MIN(largeResolutionSize.height / designResolutionSize.height, 95 | largeResolutionSize.width / designResolutionSize.width)); 96 | } 97 | // If the frame's height is larger than the height of small size. 98 | else if (frameSize.height > smallResolutionSize.height) { 99 | director->setContentScaleFactor( 100 | MIN(mediumResolutionSize.height / designResolutionSize.height, 101 | mediumResolutionSize.width / designResolutionSize.width)); 102 | } 103 | // If the frame's height is smaller than the height of medium size. 104 | else { 105 | director->setContentScaleFactor( 106 | MIN(smallResolutionSize.height / designResolutionSize.height, 107 | smallResolutionSize.width / designResolutionSize.width)); 108 | } 109 | 110 | register_all_packages(); 111 | 112 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 113 | CCLOG("Initializing Firebase for Android."); 114 | firebase::App::Create(firebase::AppOptions(), JniHelper::getEnv(), 115 | JniHelper::getActivity()); 116 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 117 | CCLOG("Initializing Firebase for iOS."); 118 | firebase::App::Create(firebase::AppOptions()); 119 | #else 120 | CCLOG("Initializing Firebase for Desktop."); 121 | CCLOG("Note: Functions in the Firebase C++ desktop API are stubs, and are " 122 | "provided for convenience only."); 123 | firebase::App::Create(firebase::AppOptions()); 124 | #endif 125 | 126 | // Create a scene. Scenes are reference counted and will auto-release on exit. 127 | // Currently doesn't compile on desktop. b/34988588 128 | auto scene = CreateFirebaseScene(); 129 | 130 | // Run the scene. 131 | director->runWithScene(scene); 132 | 133 | return true; 134 | } 135 | 136 | // This function will be called when the app is inactive. Note, when receiving a 137 | // phone call it is invoked. 138 | void AppDelegate::applicationDidEnterBackground() { 139 | Director::getInstance()->stopAnimation(); 140 | 141 | // If you use SimpleAudioEngine, it must be paused. 142 | // SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); 143 | } 144 | 145 | // this function will be called when the app is active again 146 | void AppDelegate::applicationWillEnterForeground() { 147 | Director::getInstance()->startAnimation(); 148 | 149 | // If you use SimpleAudioEngine, it must resume here. 150 | // SimpleAudioEngine::getInstance()->resumeBackgroundMusic(); 151 | } 152 | -------------------------------------------------------------------------------- /invites/Classes/FirebaseInvitesScene.cpp: -------------------------------------------------------------------------------- 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 "FirebaseInvitesScene.h" 22 | 23 | #include 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 28 | #include "platform/android/jni/JniHelper.h" 29 | #endif 30 | 31 | #include "FirebaseCocos.h" 32 | #include "firebase/future.h" 33 | #include "firebase/invites.h" 34 | 35 | USING_NS_CC; 36 | 37 | /// Padding for the UI elements. 38 | static const float kUIElementPadding = 10.0; 39 | 40 | /// The title text for the Firebase buttons. 41 | static const char* kInviteButtonText = "Invite"; 42 | 43 | /// Creates the Firebase scene. 44 | Scene* CreateFirebaseScene() { 45 | return FirebaseInvitesScene::createScene(); 46 | } 47 | 48 | /// Creates the FirebaseInvitesScene. 49 | Scene* FirebaseInvitesScene::createScene() { 50 | // Create the scene. 51 | auto scene = Scene::create(); 52 | 53 | // Create the layer. 54 | auto layer = FirebaseInvitesScene::create(); 55 | 56 | // Add the layer to the scene. 57 | scene->addChild(layer); 58 | 59 | return scene; 60 | } 61 | 62 | /// Initializes the FirebaseScene. 63 | bool FirebaseInvitesScene::init() { 64 | if (!Layer::init()) { 65 | return false; 66 | } 67 | 68 | auto visibleSize = Director::getInstance()->getVisibleSize(); 69 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 70 | 71 | // Intitialize Firebase Invites. 72 | CCLOG("Initializing the Invites with Firebase API."); 73 | firebase::invites::Initialize(*firebase::App::GetInstance()); 74 | 75 | // Create the Firebase label. 76 | auto firebaseLabel = 77 | Label::createWithTTF("Firebase Invites", "fonts/Marker Felt.ttf", 20); 78 | nextYPosition = 79 | origin.y + visibleSize.height - firebaseLabel->getContentSize().height; 80 | firebaseLabel->setPosition( 81 | cocos2d::Vec2(origin.x + visibleSize.width / 2, nextYPosition)); 82 | this->addChild(firebaseLabel, 1); 83 | 84 | const float scrollViewYPosition = nextYPosition - 85 | firebaseLabel->getContentSize().height - 86 | kUIElementPadding * 2; 87 | // Create the ScrollView on the Cocos2d thread. 88 | cocos2d::Director::getInstance() 89 | ->getScheduler() 90 | ->performFunctionInCocosThread( 91 | [=]() { this->createScrollView(scrollViewYPosition); }); 92 | 93 | // Set up the invite button. 94 | invite_button_ = createButton(true, kInviteButtonText); 95 | invite_button_->addTouchEventListener( 96 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 97 | switch (type) { 98 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 99 | firebase::invites::Invite invite; 100 | invite.title_text = "Invite Friends"; 101 | invite.message_text = "Try out this super cool sample app!"; 102 | invite.call_to_action_text = "Download now!"; 103 | firebase::invites::SendInvite(invite); 104 | invite_sent_ = true; 105 | break; 106 | } 107 | default: { 108 | break; 109 | } 110 | } 111 | }); 112 | this->addChild(invite_button_); 113 | 114 | // Create the close app menu item. 115 | auto closeAppItem = MenuItemImage::create( 116 | "CloseNormal.png", "CloseSelected.png", 117 | CC_CALLBACK_1(FirebaseScene::menuCloseAppCallback, this)); 118 | closeAppItem->setContentSize(cocos2d::Size(25, 25)); 119 | // Position the close app menu item on the top-right corner of the screen. 120 | closeAppItem->setPosition(cocos2d::Vec2( 121 | origin.x + visibleSize.width - closeAppItem->getContentSize().width / 2, 122 | origin.y + visibleSize.height - 123 | closeAppItem->getContentSize().height / 2)); 124 | 125 | // Create the Menu for touch handling. 126 | auto menu = Menu::create(closeAppItem, NULL); 127 | menu->setPosition(cocos2d::Vec2::ZERO); 128 | this->addChild(menu, 1); 129 | 130 | // Schedule the update method for this scene. 131 | this->scheduleUpdate(); 132 | 133 | return true; 134 | } 135 | 136 | // Called automatically every frame. The update is scheduled in `init()`. 137 | void FirebaseInvitesScene::update(float /*delta*/) { 138 | if (invite_sent_) { 139 | firebase::Future future = 140 | firebase::invites::SendInviteLastResult(); 141 | if (future.Status() == firebase::kFutureStatusComplete) { 142 | if (future.Error() == 0) { 143 | const firebase::invites::SendInviteResult& result = *future.Result(); 144 | if (result.invitation_ids.size() > 0) { 145 | // One or more invitations were sent. You can log the invitation IDs 146 | // here for analytics purposes, as they will be the same on the 147 | // receiving side. 148 | logMessage("Invite sent successfully!"); 149 | } 150 | else { 151 | // Zero invitations were sent. This tells us that the user canceled 152 | // sending invitations. 153 | logMessage("Invite canceled."); 154 | } 155 | } else { 156 | // error() is nonzero, which means an error occurred. You can check 157 | // future_result.error_message() for more information. 158 | logMessage("Error sending the invite. (Error %i: \"%s\")", 159 | future.Error(), future.ErrorMessage()); 160 | } 161 | invite_sent_ = false; 162 | } else { 163 | // The SendInvite() operation has not completed yet, which means the 164 | // Invites client UI is still on screen. Check the status() again soon. 165 | } 166 | } 167 | } 168 | 169 | /// Handles the user tapping on the close app menu item. 170 | void FirebaseInvitesScene::menuCloseAppCallback(Ref* pSender) { 171 | CCLOG("Cleaning up Invites C++ resources."); 172 | 173 | // Close the cocos2d-x game scene and quit the application. 174 | Director::getInstance()->end(); 175 | 176 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 177 | exit(0); 178 | #endif 179 | } 180 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Firebase C++ Cocos Samples 2 | 3 | We'd love for you to contribute to our source code and to make the Firebase C++ 4 | Cococs Samples project even better than they are today! Here are the guidelines 5 | we'd like you to follow: 6 | 7 | - [Code of Conduct](#coc) 8 | - [Question or Problem?](#question) 9 | - [Issues and Bugs](#issue) 10 | - [Feature Requests](#feature) 11 | - [Submission Guidelines](#submit) 12 | - [Coding Rules](#rules) 13 | - [Signing the CLA](#cla) 14 | 15 | ## Code of Conduct 16 | 17 | As contributors and maintainers of the Firebase C++ Cococs Samples project, we 18 | pledge to respect everyone who contributes by posting issues, updating 19 | documentation, submitting pull requests, providing feedback in comments, and 20 | any other activities. 21 | 22 | Communication through any of Firebase's channels (GitHub, StackOverflow, 23 | Google+, Twitter, etc.) must be constructive and never resort to personal 24 | attacks, trolling, public or private harassment, insults, or other 25 | unprofessional conduct. 26 | 27 | We promise to extend courtesy and respect to everyone involved in this project 28 | regardless of gender, gender identity, sexual orientation, disability, age, 29 | race, ethnicity, religion, or level of experience. We expect anyone 30 | contributing to the project to do the same. 31 | 32 | If any member of the community violates this code of conduct, the maintainers 33 | of the Firebase C++ Cococs Samples project may take action, removing issues, 34 | comments, and PRs or blocking accounts as deemed appropriate. 35 | 36 | ## Got a Question or Problem? 37 | 38 | If you have questions about how to use the Firebase C++ Cococs Samples, please 39 | direct these to [StackOverflow][stackoverflow] and use the `firebase` tag. We 40 | are also available on GitHub issues. 41 | 42 | If you feel that we're missing an important bit of documentation, feel free to 43 | file an issue so we can help. Here's an example to get you started: 44 | 45 | ``` 46 | What are you trying to do or find out more about? 47 | 48 | Where have you looked? 49 | 50 | Where did you expect to find this information? 51 | ``` 52 | 53 | ## Found an Issue? 54 | If you find a bug in the source code or a mistake in the documentation, you can 55 | help us by submitting an issue to our [GitHub Repository][github]. Even better 56 | you can submit a Pull Request with a fix. 57 | 58 | See [below](#submit) for some guidelines. 59 | 60 | ## Submission Guidelines 61 | 62 | ### Submitting an Issue 63 | Before you submit your issue, search the archive, maybe your question was 64 | already answered. 65 | 66 | If your issue appears to be a bug, and hasn't been reported, open a new issue. 67 | Help us to maximize the effort we can spend fixing issues and adding new 68 | features, by not reporting duplicate issues. Providing the following 69 | information will increase the chances of your issue being dealt with quickly: 70 | 71 | * **Overview of the Issue** - if an error is being thrown a stack trace with 72 | symbols helps 73 | * **Motivation for or Use Case** - explain why this is a bug for you 74 | * **Operating System** - is this a problem for all operating systems? 75 | * **Reproduce the Error** - provide a live example or a unambiguous set of 76 | steps. 77 | * **Related Issues** - has a similar issue been reported before? 78 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point 79 | to what might be causing the problem (line of code or commit) 80 | 81 | **If you get help, help others. Good karma rulez!** 82 | 83 | Here's a template to get you started: 84 | 85 | ``` 86 | Operating system: 87 | Operating system version: 88 | 89 | What steps will reproduce the problem: 90 | 1. 91 | 2. 92 | 3. 93 | 94 | What is the expected result? 95 | 96 | What happens instead of that? 97 | 98 | Please provide any other information below, and attach a screenshot if possible. 99 | ``` 100 | 101 | ### Submitting a Pull Request 102 | Before you submit your pull request consider the following guidelines: 103 | 104 | * Search [GitHub](https://github.com/firebase/cocos2dx-cpp-sample/pulls) for an 105 | open or closed Pull Request that relates to your submission. You don't want to 106 | duplicate effort. 107 | * Please sign our [Contributor License Agreement (CLA)](#cla) before sending 108 | pull requests. We cannot accept code without this. 109 | * Make your changes in a new git branch: 110 | 111 | ```shell 112 | git checkout -b my-fix-branch master 113 | ``` 114 | 115 | * Create your patch, **including appropriate test cases**. 116 | * Follow our [Coding Rules](#rules). 117 | * Avoid checking in files that shouldn't be tracked (e.g `.tmp`, `.idea`). 118 | We recommend using a [global](#global-gitignore) gitignore for this. 119 | * Commit your changes using a descriptive commit message. 120 | 121 | ```shell 122 | git commit -a 123 | ``` 124 | Note: the optional commit `-a` command line option will automatically "add" 125 | and "rm" edited files. 126 | 127 | * Build your changes locally and run the applications to verify they're still 128 | functional. 129 | 130 | * Push your branch to GitHub: 131 | 132 | ```shell 133 | git push origin my-fix-branch 134 | ``` 135 | 136 | * In GitHub, send a pull request to `firebase/cocos2dx-cpp-sample:master`. 137 | * If we suggest changes then: 138 | * Make the required updates. 139 | * Rebase your branch and force push to your GitHub repository (this will 140 | update your Pull Request): 141 | 142 | ```shell 143 | git rebase master -i 144 | git push origin my-fix-branch -f 145 | ``` 146 | 147 | That's it! Thank you for your contribution! 148 | 149 | #### After your pull request is merged 150 | 151 | After your pull request is merged, you can safely delete your branch and pull 152 | the changes from the main (upstream) repository: 153 | 154 | * Delete the remote branch on GitHub either through the GitHub UI or your local 155 | shell as follows: 156 | 157 | ```shell 158 | git push origin --delete my-fix-branch 159 | ``` 160 | 161 | * Check out the master branch: 162 | 163 | ```shell 164 | git checkout master -f 165 | ``` 166 | 167 | * Delete the local branch: 168 | 169 | ```shell 170 | git branch -D my-fix-branch 171 | ``` 172 | 173 | * Update your master with the latest upstream version: 174 | 175 | ```shell 176 | git pull --ff upstream master 177 | ``` 178 | 179 | ## Coding Rules 180 | 181 | We generally follow the [Google C++ style guide][cpp-style-guide]. 182 | 183 | ## Signing the CLA 184 | 185 | Please sign our [Contributor License Agreement][google-cla] (CLA) before sending 186 | pull requests. For any code changes to be accepted, the CLA must be signed. 187 | It's a quick process, we promise! 188 | 189 | *This guide was inspired by the [AngularJS contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).* 190 | 191 | [github]: https://github.com/firebase/cocos2dx-cpp-sample 192 | [google-cla]: https://cla.developers.google.com 193 | [cpp-style-guide]: https://google.github.io/styleguide/cppguide.html 194 | [stackoverflow]: http://stackoverflow.com/questions/tagged/firebase 195 | [global-gitignore]: https://help.github.com/articles/ignoring-files/#create-a-global-gitignore 196 | -------------------------------------------------------------------------------- /common/Classes/FirebaseScene.cpp: -------------------------------------------------------------------------------- 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 "FirebaseScene.h" 22 | 23 | #include 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 28 | #include "platform/android/jni/JniHelper.h" 29 | #endif 30 | 31 | #include "FirebaseCocos.h" 32 | 33 | USING_NS_CC; 34 | 35 | // The images for the Firebase buttons. 36 | static const std::string kNormalButtonImage = "NormalButtonImage.png"; 37 | static const std::string kSelectedButtonImage = "SelectedButtonImage.png"; 38 | static const std::string kDisabledButtonImage = "SelectedButtonImage.png"; 39 | 40 | /// Padding for the UI elements. 41 | static const float kUIElementPadding = 10.0; 42 | 43 | /// The title text size for the Firebase buttons. 44 | static const float kButtonTitleFontSize = 12.0; 45 | 46 | /// The content size for the Firebase buttons. 47 | static const cocos2d::Size kButtonContentSize = cocos2d::Size(150, 20); 48 | 49 | /// The factor used to determine when to resize the ScrollView's inner container 50 | /// height. 51 | static const float kScrollViewContainerHeightFactor = 0.85; 52 | 53 | /// The logging ScrollView. 54 | cocos2d::ui::ScrollView* scrollView; 55 | 56 | /// The log text for the Text Widget. 57 | cocos2d::ui::Text* logTextWidget; 58 | 59 | /// The log text. 60 | std::string logTextString; 61 | 62 | cocos2d::ui::Button* FirebaseScene::createButton( 63 | bool buttonEnabled, const std::string& buttonTitleText, 64 | const cocos2d::Color3B& buttonColor) { 65 | auto visibleSize = Director::getInstance()->getVisibleSize(); 66 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 67 | cocos2d::ui::Button* button = cocos2d::ui::Button::create( 68 | kNormalButtonImage, kSelectedButtonImage, kDisabledButtonImage); 69 | button->setEnabled(buttonEnabled); 70 | button->setColor(buttonColor); 71 | button->setTitleText(buttonTitleText); 72 | button->setTitleFontSize(kButtonTitleFontSize); 73 | button->ignoreContentAdaptWithSize(false); 74 | button->setContentSize(kButtonContentSize); 75 | nextYPosition -= button->getContentSize().height + kUIElementPadding; 76 | button->setPosition( 77 | cocos2d::Vec2(origin.x + visibleSize.width / 4, nextYPosition)); 78 | 79 | return button; 80 | } 81 | 82 | cocos2d::ui::Button* FirebaseScene::createButton( 83 | bool buttonEnabled, const std::string& buttonTitleText) { 84 | return createButton(buttonEnabled, buttonTitleText, cocos2d::Color3B::WHITE); 85 | } 86 | 87 | cocos2d::ui::TextField* FirebaseScene::createTextField( 88 | const char* placeholder) { 89 | auto visibleSize = Director::getInstance()->getVisibleSize(); 90 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 91 | cocos2d::ui::TextField* text_field = 92 | ui::TextField::create(placeholder, "fonts/arial.ttf", 12); 93 | text_field->setPlaceHolderColor(Color3B::WHITE); 94 | nextYPosition -= text_field->getContentSize().height + kUIElementPadding; 95 | text_field->setPosition( 96 | cocos2d::Vec2(origin.x + visibleSize.width / 4, nextYPosition)); 97 | return text_field; 98 | } 99 | 100 | void FirebaseScene::createScrollView(float yPosition, float widthFraction) { 101 | cocos2d::Size visibleSize = Director::getInstance()->getVisibleSize(); 102 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 103 | 104 | scrollView = cocos2d::ui::ScrollView::create(); 105 | auto scrollViewFrameSize = 106 | Size(visibleSize.width * (1 - widthFraction), yPosition); 107 | scrollView->setContentSize(scrollViewFrameSize); 108 | scrollView->setPosition( 109 | cocos2d::Point(origin.x + visibleSize.width * widthFraction, origin.y)); 110 | cocos2d::Size scrollViewContainerSize = 111 | cocos2d::Size(scrollViewFrameSize.width, scrollViewFrameSize.height); 112 | scrollView->setInnerContainerSize(scrollViewContainerSize); 113 | 114 | logTextWidget = cocos2d::ui::Text::create("", "fonts/arial.ttf", 12); 115 | logTextWidget->setTextAreaSize( 116 | cocos2d::Size(scrollViewContainerSize.width, 0)); 117 | scrollView->addChild(logTextWidget); 118 | 119 | this->addChild(scrollView); 120 | } 121 | 122 | void FirebaseScene::createScrollView(float yPosition) { 123 | createScrollView(yPosition, 0.5f); 124 | } 125 | 126 | /// Adds text to the log TextWidget. 127 | void FirebaseScene::logMessage(std::string format, ...) { 128 | static const int kLineBufferSize = 100; 129 | char buffer[kLineBufferSize + 2]; 130 | 131 | va_list list; 132 | va_start(list, format); 133 | vsnprintf(buffer, kLineBufferSize, format.c_str(), list); 134 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 135 | __android_log_vprint(ANDROID_LOG_INFO, "FIREBASE-COCOS", format.c_str(), 136 | list); 137 | #endif 138 | va_end(list); 139 | logTextString.append("\n"); 140 | logTextString.append(buffer); 141 | 142 | // Update the log TextWidget and the ScrollView's inner container size on the 143 | // Cocos2d thread. 144 | cocos2d::Director::getInstance() 145 | ->getScheduler() 146 | ->performFunctionInCocosThread([=]() { 147 | logTextWidget->setString(logTextString); 148 | cocos2d::Size scrollViewContainerSize = 149 | scrollView->getInnerContainerSize(); 150 | // Check to see if the ScrollView's inner container needs to be resized. 151 | if (logTextWidget->getContentSize().height / 152 | scrollViewContainerSize.height >= 153 | kScrollViewContainerHeightFactor) { 154 | cocos2d::Size newScrollViewContainerSize = 155 | cocos2d::Size(scrollViewContainerSize.width, 156 | scrollViewContainerSize.height * 2); 157 | scrollView->setInnerContainerSize(newScrollViewContainerSize); 158 | scrollViewContainerSize = scrollView->getInnerContainerSize(); 159 | } 160 | logTextWidget->setPosition(cocos2d::Point( 161 | scrollViewContainerSize.width - 162 | logTextWidget->getContentSize().width / 2, 163 | scrollViewContainerSize.height + 164 | kUIElementPadding - 165 | logTextWidget->getContentSize().height / 2)); 166 | float scrollPercent = logTextWidget->getContentSize().height / 167 | scrollViewContainerSize.height; 168 | scrollView->scrollToPercentVertical(scrollPercent * 100, 1.0, false); 169 | }); 170 | } 171 | 172 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 173 | // Returns the iOS RootViewController's main view (i.e. the EAGLView). 174 | WindowContext getWindowContext() { 175 | return (id)Director::getInstance()->getOpenGLView()->getEAGLView(); 176 | } 177 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 178 | // Returns the Android Activity. 179 | WindowContext getWindowContext() { return JniHelper::getActivity(); } 180 | #else 181 | WindowContext getWindowContext() { return nullptr; } 182 | #endif 183 | -------------------------------------------------------------------------------- /messaging/Classes/FirebaseMessagingScene.cpp: -------------------------------------------------------------------------------- 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 "FirebaseMessagingScene.h" 22 | 23 | #include 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 28 | #include "platform/android/jni/JniHelper.h" 29 | #endif 30 | 31 | #include "FirebaseCocos.h" 32 | #include "firebase/messaging.h" 33 | 34 | USING_NS_CC; 35 | 36 | /// Padding for the UI elements. 37 | static const float kUIElementPadding = 10.0; 38 | 39 | class FirebaseMessagingSceneListener : public firebase::messaging::Listener { 40 | public: 41 | FirebaseMessagingSceneListener(FirebaseMessagingScene* scene) 42 | : scene_(scene) {} 43 | 44 | void OnMessage(const firebase::messaging::Message& message) override { 45 | scene_->logMessage("Recieved a new message"); 46 | if (!message.from.empty()) { 47 | scene_->logMessage("from: %s", message.from.c_str()); 48 | } 49 | if (!message.error.empty()) { 50 | scene_->logMessage("error: %s", message.error.c_str()); 51 | } 52 | if (!message.message_id.empty()) { 53 | scene_->logMessage("message_id: %s", message.message_id.c_str()); 54 | } 55 | if (!message.data.empty()) { 56 | scene_->logMessage("data:"); 57 | for (const auto& field : message.data) { 58 | scene_->logMessage( 59 | " %s: %s", field.first.c_str(), field.second.c_str()); 60 | } 61 | } 62 | if (message.notification) { 63 | scene_->logMessage("notification:"); 64 | if (!message.notification->title.empty()) { 65 | scene_->logMessage(" title: %s", message.notification->title.c_str()); 66 | } 67 | if (!message.notification->body.empty()) { 68 | scene_->logMessage(" body: %s", message.notification->body.c_str()); 69 | } 70 | if (!message.notification->icon.empty()) { 71 | scene_->logMessage(" icon: %s", message.notification->icon.c_str()); 72 | } 73 | if (!message.notification->tag.empty()) { 74 | scene_->logMessage(" tag: %s", message.notification->tag.c_str()); 75 | } 76 | if (!message.notification->color.empty()) { 77 | scene_->logMessage(" color: %s", message.notification->color.c_str()); 78 | } 79 | if (!message.notification->sound.empty()) { 80 | scene_->logMessage(" sound: %s", message.notification->sound.c_str()); 81 | } 82 | if (!message.notification->click_action.empty()) { 83 | scene_->logMessage(" click_action: %s", 84 | message.notification->click_action.c_str()); 85 | } 86 | } 87 | } 88 | 89 | void OnTokenReceived(const char* token) override { 90 | // To send a message to a specific instance of your app a registration token 91 | // is required. These tokens are unique for each instance of the app. When 92 | // messaging::Initialize is called, a request is sent to the Firebase Cloud 93 | // Messaging server to generate a token. When that token is ready, 94 | // OnTokenReceived will be called. The token should be cached locally so 95 | // that a request doesn't need to be generated each time the app is started. 96 | // 97 | // Once a token is generated is should be sent to your app server, which can 98 | // then use it to send messages to users. 99 | scene_->logMessage("Recieved Registration Token: %s", token); 100 | } 101 | 102 | private: 103 | FirebaseMessagingScene* scene_; 104 | }; 105 | 106 | /// Creates the Firebase scene. 107 | Scene* CreateFirebaseScene() { 108 | return FirebaseMessagingScene::createScene(); 109 | } 110 | 111 | /// Creates the FirebaseMessagingScene. 112 | Scene* FirebaseMessagingScene::createScene() { 113 | // Create the scene. 114 | auto scene = Scene::create(); 115 | 116 | // Create the layer. 117 | auto layer = FirebaseMessagingScene::create(); 118 | 119 | // Add the layer to the scene. 120 | scene->addChild(layer); 121 | 122 | return scene; 123 | } 124 | 125 | /// Initializes the FirebaseScene. 126 | bool FirebaseMessagingScene::init() { 127 | if (!Layer::init()) { 128 | return false; 129 | } 130 | 131 | auto visibleSize = Director::getInstance()->getVisibleSize(); 132 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 133 | 134 | // Create the Firebase label. 135 | auto firebaseLabel = 136 | Label::createWithTTF("Firebase Messaging", "fonts/Marker Felt.ttf", 20); 137 | nextYPosition = 138 | origin.y + visibleSize.height - firebaseLabel->getContentSize().height; 139 | firebaseLabel->setPosition( 140 | cocos2d::Vec2(origin.x + visibleSize.width / 2, nextYPosition)); 141 | this->addChild(firebaseLabel, 1); 142 | 143 | const float scrollViewYPosition = nextYPosition - 144 | firebaseLabel->getContentSize().height - 145 | kUIElementPadding * 2; 146 | // Create the ScrollView on the Cocos2d thread. 147 | cocos2d::Director::getInstance() 148 | ->getScheduler() 149 | ->performFunctionInCocosThread( 150 | [=]() { this->createScrollView(scrollViewYPosition, 0.0f); }); 151 | 152 | // Intitialize Firebase Messaging. (This must happen after the log ui widget 153 | // is set up so that the listener has a place to send log messages to) 154 | CCLOG("Initializing the Messaging with Firebase API."); 155 | firebase::messaging::Initialize(*firebase::App::GetInstance(), 156 | new FirebaseMessagingSceneListener(this)); 157 | 158 | // Create the close app menu item. 159 | auto closeAppItem = MenuItemImage::create( 160 | "CloseNormal.png", "CloseSelected.png", 161 | CC_CALLBACK_1(FirebaseScene::menuCloseAppCallback, this)); 162 | closeAppItem->setContentSize(cocos2d::Size(25, 25)); 163 | // Position the close app menu item on the top-right corner of the screen. 164 | closeAppItem->setPosition(cocos2d::Vec2( 165 | origin.x + visibleSize.width - closeAppItem->getContentSize().width / 2, 166 | origin.y + visibleSize.height - 167 | closeAppItem->getContentSize().height / 2)); 168 | 169 | // Create the Menu for touch handling. 170 | auto menu = Menu::create(closeAppItem, NULL); 171 | menu->setPosition(cocos2d::Vec2::ZERO); 172 | this->addChild(menu, 1); 173 | 174 | // Schedule the update method for this scene. 175 | this->scheduleUpdate(); 176 | 177 | return true; 178 | } 179 | 180 | // Called automatically every frame. The update is scheduled in `init()`. 181 | void FirebaseMessagingScene::update(float /*delta*/) {} 182 | 183 | /// Handles the user tapping on the close app menu item. 184 | void FirebaseMessagingScene::menuCloseAppCallback(Ref* pSender) { 185 | CCLOG("Cleaning up Messaging C++ resources."); 186 | 187 | // Close the cocos2d-x game scene and quit the application. 188 | Director::getInstance()->end(); 189 | 190 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 191 | exit(0); 192 | #endif 193 | } 194 | -------------------------------------------------------------------------------- /remote_config/Classes/FirebaseRemoteConfigScene.cpp: -------------------------------------------------------------------------------- 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 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 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 Remote Config", "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 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(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 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 | } 238 | -------------------------------------------------------------------------------- /auth/Classes/FirebaseAuthScene.cpp: -------------------------------------------------------------------------------- 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 "FirebaseAuthScene.h" 22 | 23 | #include 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 28 | #include "platform/android/jni/JniHelper.h" 29 | #endif 30 | 31 | #include "FirebaseCocos.h" 32 | #include "firebase/auth.h" 33 | 34 | USING_NS_CC; 35 | 36 | /// Padding for the UI elements. 37 | static const float kUIElementPadding = 10.0; 38 | 39 | /// Placeholder labels for the text fields. 40 | static const char* kEmailPlaceholderText = "Email"; 41 | static const char* kPasswordPlaceholderText = "Password"; 42 | 43 | /// Creates the Firebase scene. 44 | Scene* CreateFirebaseScene() { 45 | return FirebaseAuthScene::createScene(); 46 | } 47 | 48 | /// Creates the FirebaseAuthScene. 49 | Scene* FirebaseAuthScene::createScene() { 50 | // Create the scene. 51 | auto scene = Scene::create(); 52 | 53 | // Create the layer. 54 | auto layer = FirebaseAuthScene::create(); 55 | 56 | // Add the layer to the scene. 57 | scene->addChild(layer); 58 | 59 | return scene; 60 | } 61 | 62 | /// Initializes the FirebaseScene. 63 | bool FirebaseAuthScene::init() { 64 | using firebase::auth::Auth; 65 | using firebase::auth::Credential; 66 | using firebase::auth::EmailAuthProvider; 67 | 68 | if (!Layer::init()) { 69 | return false; 70 | } 71 | 72 | auto visibleSize = Director::getInstance()->getVisibleSize(); 73 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 74 | 75 | CCLOG("Initializing the Auth with Firebase API."); 76 | Auth* auth = Auth::GetAuth(firebase::App::GetInstance()); 77 | 78 | // Create the Firebase label. 79 | auto firebaseLabel = 80 | Label::createWithTTF("Firebase Auth", "fonts/Marker Felt.ttf", 20); 81 | nextYPosition = 82 | origin.y + visibleSize.height - firebaseLabel->getContentSize().height; 83 | firebaseLabel->setPosition( 84 | cocos2d::Vec2(origin.x + visibleSize.width / 2, nextYPosition)); 85 | this->addChild(firebaseLabel, 1); 86 | 87 | const float scrollViewYPosition = nextYPosition - 88 | firebaseLabel->getContentSize().height - 89 | kUIElementPadding * 2; 90 | // Create the ScrollView on the Cocos2d thread. 91 | cocos2d::Director::getInstance() 92 | ->getScheduler() 93 | ->performFunctionInCocosThread( 94 | [=]() { this->createScrollView(scrollViewYPosition); }); 95 | 96 | logMessage("Created the Auth %x class for the Firebase app.", 97 | static_cast(reinterpret_cast(auth))); 98 | 99 | // It's possible for current_user() to be non-null if the previous run 100 | // left us in a signed-in state. 101 | if (auth->current_user() == nullptr) { 102 | logMessage("No user signed in at creation time."); 103 | } else { 104 | logMessage("Current user %s already signed in, so signing them out.", 105 | auth->current_user()->display_name().c_str()); 106 | } 107 | 108 | email_text_field_ = createTextField(kEmailPlaceholderText); 109 | this->addChild(email_text_field_); 110 | 111 | password_text_field_ = createTextField(kPasswordPlaceholderText); 112 | password_text_field_->setPasswordEnabled(true); 113 | this->addChild(password_text_field_); 114 | 115 | register_user_button_ = createButton(true, "Register user"); 116 | register_user_button_->addTouchEventListener( 117 | [this, auth](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 118 | switch (type) { 119 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 120 | this->logMessage("Registering user..."); 121 | const char* email = email_text_field_->getString().c_str(); 122 | const char* password = password_text_field_->getString().c_str(); 123 | this->create_user_future_ = 124 | auth->CreateUserWithEmailAndPassword(email, password); 125 | this->register_user_button_->setEnabled(false); 126 | break; 127 | } 128 | default: { 129 | break; 130 | } 131 | } 132 | }); 133 | this->addChild(register_user_button_); 134 | 135 | credentialed_sign_in_button_ = createButton(true, "Sign in"); 136 | credentialed_sign_in_button_->addTouchEventListener( 137 | [this, auth](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 138 | switch (type) { 139 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 140 | this->logMessage("Signing in..."); 141 | const char* email = email_text_field_->getString().c_str(); 142 | const char* password = password_text_field_->getString().c_str(); 143 | Credential email_cred = 144 | EmailAuthProvider::GetCredential(email, password); 145 | this->sign_in_future_ = auth->SignInWithCredential(email_cred); 146 | this->credentialed_sign_in_button_->setEnabled(false); 147 | this->anonymous_sign_in_button_->setEnabled(false); 148 | this->sign_out_button_->setEnabled(true); 149 | this->anonymous_sign_in_ = false; 150 | break; 151 | } 152 | default: { 153 | break; 154 | } 155 | } 156 | }); 157 | this->addChild(credentialed_sign_in_button_); 158 | 159 | anonymous_sign_in_button_ = createButton(true, "Sign in anonymously"); 160 | anonymous_sign_in_button_->addTouchEventListener( 161 | [this, auth](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 162 | switch (type) { 163 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 164 | this->logMessage("Signing in anonymously..."); 165 | // Anonymous sign in must be enabled in the Firebase Console. 166 | this->sign_in_future_ = auth->SignInAnonymously(); 167 | this->credentialed_sign_in_button_->setEnabled(false); 168 | this->anonymous_sign_in_button_->setEnabled(false); 169 | this->sign_out_button_->setEnabled(true); 170 | this->anonymous_sign_in_ = true; 171 | break; 172 | } 173 | default: { 174 | break; 175 | } 176 | } 177 | }); 178 | this->addChild(anonymous_sign_in_button_); 179 | 180 | sign_out_button_ = createButton(false, "Sign out"); 181 | sign_out_button_->addTouchEventListener( 182 | [this, auth](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 183 | switch (type) { 184 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 185 | this->logMessage("Signed out"); 186 | auth->SignOut(); 187 | this->credentialed_sign_in_button_->setEnabled(true); 188 | this->anonymous_sign_in_button_->setEnabled(true); 189 | this->sign_out_button_->setEnabled(false); 190 | break; 191 | } 192 | default: { 193 | break; 194 | } 195 | } 196 | }); 197 | this->addChild(sign_out_button_); 198 | 199 | // Create the close app menu item. 200 | auto closeAppItem = MenuItemImage::create( 201 | "CloseNormal.png", "CloseSelected.png", 202 | CC_CALLBACK_1(FirebaseScene::menuCloseAppCallback, this)); 203 | closeAppItem->setContentSize(cocos2d::Size(25, 25)); 204 | // Position the close app menu item on the top-right corner of the screen. 205 | closeAppItem->setPosition(cocos2d::Vec2( 206 | origin.x + visibleSize.width - closeAppItem->getContentSize().width / 2, 207 | origin.y + visibleSize.height - 208 | closeAppItem->getContentSize().height / 2)); 209 | 210 | // Create the Menu for touch handling. 211 | auto menu = Menu::create(closeAppItem, NULL); 212 | menu->setPosition(cocos2d::Vec2::ZERO); 213 | this->addChild(menu, 1); 214 | 215 | // Schedule the update method for this scene. 216 | this->scheduleUpdate(); 217 | 218 | return true; 219 | } 220 | 221 | // Called automatically every frame. The update is scheduled in `init()`. 222 | void FirebaseAuthScene::update(float /*delta*/) { 223 | using firebase::auth::AuthError; 224 | if (create_user_future_.status() == firebase::kFutureStatusComplete) { 225 | const AuthError error = static_cast(create_user_future_.error()); 226 | if (error == firebase::auth::kAuthErrorNone) { 227 | logMessage("Created new user successfully."); 228 | } else { 229 | logMessage("ERROR: User creation failed: %d, `%s`", error, 230 | sign_in_future_.error_message()); 231 | } 232 | this->register_user_button_->setEnabled(true); 233 | create_user_future_.Release(); 234 | } 235 | if (sign_in_future_.status() == firebase::kFutureStatusComplete) { 236 | const AuthError error = static_cast(sign_in_future_.error()); 237 | if (error == firebase::auth::kAuthErrorNone) { 238 | logMessage("Signed in successfully."); 239 | } else { 240 | logMessage("ERROR: Sign in failed: %d, `%s`", error, 241 | sign_in_future_.error_message()); 242 | if (this->anonymous_sign_in_) { 243 | logMessage("You may need to enable anonymous login in the Firebase " 244 | "Console."); 245 | logMessage("(In the console, navigate to Authentication > " 246 | "Sign-in Method > Anonymous and click Enable)"); 247 | } 248 | this->credentialed_sign_in_button_->setEnabled(true); 249 | this->anonymous_sign_in_button_->setEnabled(true); 250 | this->sign_out_button_->setEnabled(false); 251 | } 252 | sign_in_future_.Release(); 253 | } 254 | } 255 | 256 | /// Handles the user tapping on the close app menu item. 257 | void FirebaseAuthScene::menuCloseAppCallback(Ref* pSender) { 258 | CCLOG("Cleaning up Auth C++ resources."); 259 | 260 | // Close the cocos2d-x game scene and quit the application. 261 | Director::getInstance()->end(); 262 | 263 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 264 | exit(0); 265 | #endif 266 | } 267 | -------------------------------------------------------------------------------- /analytics/Classes/FirebaseAnalyticsScene.cpp: -------------------------------------------------------------------------------- 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 "FirebaseAnalyticsScene.h" 22 | 23 | #include 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 28 | #include "platform/android/jni/JniHelper.h" 29 | #endif 30 | 31 | #include "FirebaseCocos.h" 32 | #include "firebase/analytics.h" 33 | #include "firebase/app.h" 34 | #include "firebase/future.h" 35 | 36 | USING_NS_CC; 37 | 38 | /// Padding for the UI elements. 39 | static const float kUIElementPadding = 10.0; 40 | 41 | /// The title text for the Firebase buttons. 42 | static const char* kBlueButtonText = "Fire Blue Event"; 43 | static const char* kRedButtonText = "Fire Red Event"; 44 | static const char* kYellowButtonText = "Fire Yellow Event"; 45 | static const char* kGreenButtonText = "Fire Green Event"; 46 | 47 | /// The colors for the buttons. 48 | static const cocos2d::Color3B kBlueButtonColor(0x48, 0x85, 0xed); 49 | static const cocos2d::Color3B kRedButtonColor(0xdb, 0x32, 0x36); 50 | static const cocos2d::Color3B kYellowButtonColor(0xf4, 0xc2, 0x0d); 51 | static const cocos2d::Color3B kGreenButtonColor(0x3c, 0xba, 0x54); 52 | 53 | static const char* kButtonClickEvent = "button_clicked"; 54 | static const char* kButtonColor = "button_color"; 55 | 56 | /// Creates the Firebase scene. 57 | Scene* CreateFirebaseScene() { 58 | return FirebaseAnalyticsScene::createScene(); 59 | } 60 | 61 | /// Creates the FirebaseAnalyticsScene. 62 | Scene* FirebaseAnalyticsScene::createScene() { 63 | // Create the scene. 64 | auto scene = Scene::create(); 65 | 66 | // Create the layer. 67 | auto layer = FirebaseAnalyticsScene::create(); 68 | 69 | // Add the layer to the scene. 70 | scene->addChild(layer); 71 | 72 | return scene; 73 | } 74 | 75 | /// Initializes the FirebaseScene. 76 | bool FirebaseAnalyticsScene::init() { 77 | if (!Layer::init()) { 78 | return false; 79 | } 80 | 81 | auto visibleSize = Director::getInstance()->getVisibleSize(); 82 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 83 | 84 | // Intitialize Firebase Analytics. 85 | CCLOG("Initializing the Analytics with Firebase API."); 86 | firebase::analytics::Initialize(*firebase::App::GetInstance()); 87 | 88 | // Create the Firebase label. 89 | auto firebaseLabel = 90 | Label::createWithTTF("Firebase Analytics", "fonts/Marker Felt.ttf", 20); 91 | nextYPosition = 92 | origin.y + visibleSize.height - firebaseLabel->getContentSize().height; 93 | firebaseLabel->setPosition( 94 | cocos2d::Vec2(origin.x + visibleSize.width / 2, nextYPosition)); 95 | this->addChild(firebaseLabel, 1); 96 | 97 | const float scrollViewYPosition = nextYPosition - 98 | firebaseLabel->getContentSize().height - 99 | kUIElementPadding * 2; 100 | // Create the ScrollView on the Cocos2d thread. 101 | cocos2d::Director::getInstance() 102 | ->getScheduler() 103 | ->performFunctionInCocosThread( 104 | [=]() { this->createScrollView(scrollViewYPosition); }); 105 | 106 | // Set up the blue button. 107 | blue_button_ = createButton(true, kBlueButtonText, kBlueButtonColor); 108 | blue_button_->addTouchEventListener( 109 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 110 | switch (type) { 111 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 112 | // When the blue button is clicked it logs an event with parameters 113 | // that indicate the color of the button was blue, as well as how 114 | // many times the blue button was clicked. 115 | this->blue_button_click_count_++; 116 | this->total_button_click_count_++; 117 | logMessage("Clicked the Blue Button. Total blue button clicks: %i", 118 | this->blue_button_click_count_); 119 | 120 | const firebase::analytics::Parameter kButtonClickParameters[] = { 121 | firebase::analytics::Parameter(kButtonColor, "blue"), 122 | firebase::analytics::Parameter("blue_button_click_count", 123 | this->blue_button_click_count_), 124 | }; 125 | firebase::analytics::LogEvent( 126 | kButtonClickEvent, kButtonClickParameters, 127 | sizeof(kButtonClickParameters) / 128 | sizeof(kButtonClickParameters[0])); 129 | 130 | this->previous_button_clicked_ = "blue"; 131 | break; 132 | } 133 | default: { 134 | break; 135 | } 136 | } 137 | }); 138 | this->addChild(blue_button_); 139 | 140 | // Set up the red button. 141 | red_button_ = createButton(true, kRedButtonText, kRedButtonColor); 142 | red_button_->addTouchEventListener( 143 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 144 | switch (type) { 145 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 146 | // When the red button is clicked it logs an event with parameters 147 | // that indicate the color of the button was red, as well as how 148 | // many times any button was clicked. 149 | this->total_button_click_count_++; 150 | logMessage("Clicked the Red Button. Total button clicks: %i", 151 | this->total_button_click_count_); 152 | 153 | const firebase::analytics::Parameter kButtonClickParameters[] = { 154 | firebase::analytics::Parameter(kButtonColor, "red"), 155 | firebase::analytics::Parameter("total_button_click_count", 156 | this->total_button_click_count_), 157 | }; 158 | firebase::analytics::LogEvent( 159 | kButtonClickEvent, kButtonClickParameters, 160 | sizeof(kButtonClickParameters) / 161 | sizeof(kButtonClickParameters[0])); 162 | 163 | this->previous_button_clicked_ = "red"; 164 | break; 165 | } 166 | default: { 167 | break; 168 | } 169 | } 170 | }); 171 | this->addChild(red_button_); 172 | 173 | // Set up the yellow button. 174 | yellow_button_ = createButton(true, kYellowButtonText, kYellowButtonColor); 175 | yellow_button_->addTouchEventListener( 176 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 177 | switch (type) { 178 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 179 | // When the yellow button is clicked it logs an event with 180 | // parameters that indicate the color of the button was yellow, as 181 | // well as the color of the previous button that was clicked. 182 | this->total_button_click_count_++; 183 | logMessage("Clicked the Yellow Button. Previous button was: %s", 184 | this->previous_button_clicked_); 185 | 186 | const firebase::analytics::Parameter kButtonClickParameters[] = { 187 | firebase::analytics::Parameter(kButtonColor, "yellow"), 188 | firebase::analytics::Parameter("previous_button", 189 | this->previous_button_clicked_), 190 | }; 191 | firebase::analytics::LogEvent( 192 | kButtonClickEvent, kButtonClickParameters, 193 | sizeof(kButtonClickParameters) / 194 | sizeof(kButtonClickParameters[0])); 195 | 196 | this->previous_button_clicked_ = "yellow"; 197 | break; 198 | } 199 | default: { 200 | break; 201 | } 202 | } 203 | }); 204 | this->addChild(yellow_button_); 205 | 206 | // Set up the green button. 207 | green_button_ = createButton(true, kGreenButtonText, kGreenButtonColor); 208 | green_button_->addTouchEventListener( 209 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 210 | switch (type) { 211 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 212 | // When the green button is clicked it logs an event with 213 | // parameters that indicate the color of the button was green, as 214 | // well as what fraction of button clicks were made on the green 215 | // button. 216 | this->total_button_click_count_++; 217 | this->green_button_click_count_++; 218 | float ratio = static_cast(this->green_button_click_count_) / 219 | this->total_button_click_count_; 220 | logMessage("Clicked the Green Button. Green button ratio: %f", 221 | ratio); 222 | 223 | const firebase::analytics::Parameter kButtonClickParameters[] = { 224 | firebase::analytics::Parameter(kButtonColor, "green"), 225 | firebase::analytics::Parameter("green_click_ratio", ratio), 226 | }; 227 | firebase::analytics::LogEvent( 228 | kButtonClickEvent, kButtonClickParameters, 229 | sizeof(kButtonClickParameters) / 230 | sizeof(kButtonClickParameters[0])); 231 | 232 | this->previous_button_clicked_ = "green"; 233 | break; 234 | } 235 | default: { 236 | break; 237 | } 238 | } 239 | }); 240 | this->addChild(green_button_); 241 | 242 | // Create the close app menu item. 243 | auto closeAppItem = MenuItemImage::create( 244 | "CloseNormal.png", "CloseSelected.png", 245 | CC_CALLBACK_1(FirebaseScene::menuCloseAppCallback, this)); 246 | closeAppItem->setContentSize(cocos2d::Size(25, 25)); 247 | // Position the close app menu item on the top-right corner of the screen. 248 | closeAppItem->setPosition(cocos2d::Vec2( 249 | origin.x + visibleSize.width - closeAppItem->getContentSize().width / 2, 250 | origin.y + visibleSize.height - 251 | closeAppItem->getContentSize().height / 2)); 252 | 253 | // Create the Menu for touch handling. 254 | auto menu = Menu::create(closeAppItem, NULL); 255 | menu->setPosition(cocos2d::Vec2::ZERO); 256 | this->addChild(menu, 1); 257 | 258 | // Schedule the update method for this scene. 259 | this->scheduleUpdate(); 260 | 261 | return true; 262 | } 263 | 264 | // Called automatically every frame. The update is scheduled in `init()`. 265 | void FirebaseAnalyticsScene::update(float /*delta*/) {} 266 | 267 | /// Handles the user tapping on the close app menu item. 268 | void FirebaseAnalyticsScene::menuCloseAppCallback(Ref* pSender) { 269 | CCLOG("Cleaning up Analytics C++ resources."); 270 | 271 | // Close the cocos2d-x game scene and quit the application. 272 | Director::getInstance()->end(); 273 | 274 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 275 | exit(0); 276 | #endif 277 | } 278 | -------------------------------------------------------------------------------- /storage/Classes/FirebaseStorageScene.cpp: -------------------------------------------------------------------------------- 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 "FirebaseStorageScene.h" 22 | 23 | #include 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 28 | #include "platform/android/jni/JniHelper.h" 29 | #endif 30 | 31 | #include "FirebaseCocos.h" 32 | #include "firebase/auth.h" 33 | #include "firebase/storage.h" 34 | #include "firebase/future.h" 35 | 36 | USING_NS_CC; 37 | 38 | /// Padding for the UI elements. 39 | static const float kUIElementPadding = 10.0; 40 | 41 | /// Placeholder labels for the text fields. 42 | static const char* kKeyPlaceholderText = "Key"; 43 | static const char* kValuePlaceholderText = "Value"; 44 | 45 | static const char* kTestAppData = "test_app_data"; 46 | 47 | void StorageListener::OnPaused(firebase::storage::Controller*) {} 48 | 49 | void StorageListener::OnProgress(firebase::storage::Controller* controller) { 50 | int transferred = controller->bytes_transferred(); 51 | int total = controller->total_byte_count(); 52 | if (total > 0) { 53 | int percent = 100 * transferred / total; 54 | scene_->logMessage("Transfer %i%% (%i/%i)", percent, transferred, total); 55 | } 56 | } 57 | 58 | /// Creates the Firebase scene. 59 | Scene* CreateFirebaseScene() { 60 | return FirebaseStorageScene::createScene(); 61 | } 62 | 63 | /// Creates the FirebaseStorageScene. 64 | Scene* FirebaseStorageScene::createScene() { 65 | // Create the scene. 66 | auto scene = Scene::create(); 67 | 68 | // Create the layer. 69 | auto layer = FirebaseStorageScene::create(); 70 | 71 | // Add the layer to the scene. 72 | scene->addChild(layer); 73 | 74 | return scene; 75 | } 76 | 77 | /// Initializes the FirebaseScene. 78 | bool FirebaseStorageScene::init() { 79 | if (!Layer::init()) { 80 | return false; 81 | } 82 | 83 | listener_.set_scene(this); 84 | 85 | auto visibleSize = Director::getInstance()->getVisibleSize(); 86 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 87 | 88 | // Create the Firebase label. 89 | auto firebaseLabel = 90 | Label::createWithTTF("Firebase Storage", "fonts/Marker Felt.ttf", 20); 91 | nextYPosition = 92 | origin.y + visibleSize.height - firebaseLabel->getContentSize().height; 93 | firebaseLabel->setPosition( 94 | cocos2d::Vec2(origin.x + visibleSize.width / 2, nextYPosition)); 95 | this->addChild(firebaseLabel, 1); 96 | 97 | const float scrollViewYPosition = nextYPosition - 98 | firebaseLabel->getContentSize().height - 99 | kUIElementPadding * 2; 100 | // Create the ScrollView on the Cocos2d thread. 101 | cocos2d::Director::getInstance() 102 | ->getScheduler() 103 | ->performFunctionInCocosThread( 104 | [=]() { this->createScrollView(scrollViewYPosition); }); 105 | 106 | // Use ModuleInitializer to initialize both Auth and Storage, ensuring no 107 | // dependencies are missing. 108 | void* initialize_targets[] = {&auth_, &storage_}; 109 | 110 | CCLOG("Initializing the Storage with Firebase API."); 111 | const firebase::ModuleInitializer::InitializerFn initializers[] = { 112 | [](firebase::App* app, void* data) { 113 | void** targets = reinterpret_cast(data); 114 | firebase::InitResult result; 115 | *reinterpret_cast(targets[0]) = 116 | firebase::auth::Auth::GetAuth(app, &result); 117 | return result; 118 | }, 119 | [](firebase::App* app, void* data) { 120 | void** targets = reinterpret_cast(data); 121 | firebase::InitResult result; 122 | *reinterpret_cast(targets[1]) = 123 | firebase::storage::Storage::GetInstance(app, &result); 124 | return result; 125 | }}; 126 | 127 | // There are two ways to track long running operations: (1) retrieve the 128 | // future using a LastResult function or (2) Cache the future manually. 129 | // 130 | // Here we use method 1: the future is not cached but will be later retrieved 131 | // using InitializeLastResult. Which method is best for your app depends on 132 | // your use case. 133 | initializer_.Initialize( 134 | firebase::App::GetInstance(), initialize_targets, initializers, 135 | sizeof(initializers) / sizeof(initializers[0])); 136 | 137 | logMessage("Created the Storage %x class for the Firebase app.", 138 | static_cast(reinterpret_cast(storage_))); 139 | 140 | key_text_field_ = createTextField(kKeyPlaceholderText); 141 | this->addChild(key_text_field_); 142 | 143 | value_text_field_ = createTextField(kValuePlaceholderText); 144 | this->addChild(value_text_field_); 145 | 146 | get_bytes_button_ = createButton(false, "Query"); 147 | get_bytes_button_->addTouchEventListener( 148 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 149 | switch (type) { 150 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 151 | const char* key = key_text_field_->getString().c_str(); 152 | firebase::storage::StorageReference reference = 153 | this->storage_->GetReference(kTestAppData).Child(key); 154 | this->logMessage("Querying key `%s`.", key); 155 | // There are two ways to track long running operations: 156 | // (1) retrieve the future using a LastResult function or (2) Cache 157 | // the future manually. 158 | // 159 | // Here (and below in the put_bytes_button_) we use method 2: 160 | // caching the future. Which method is best for your app depends on 161 | // your use case. 162 | get_bytes_future_ = reference.GetBytes( 163 | this->byte_buffer_, kBufferSize, &this->listener_); 164 | this->get_bytes_button_->setEnabled(false); 165 | this->put_bytes_button_->setEnabled(false); 166 | break; 167 | } 168 | default: { 169 | break; 170 | } 171 | } 172 | }); 173 | this->addChild(get_bytes_button_); 174 | 175 | put_bytes_button_ = createButton(false, "Set"); 176 | put_bytes_button_->addTouchEventListener( 177 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 178 | switch (type) { 179 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 180 | const char* key = key_text_field_->getString().c_str(); 181 | const char* value = value_text_field_->getString().c_str(); 182 | size_t value_size = value_text_field_->getString().size(); 183 | firebase::storage::StorageReference reference = 184 | this->storage_->GetReference(kTestAppData).Child(key); 185 | this->logMessage("Setting key `%s` to `%s`.", key, value); 186 | this->put_bytes_future_ = reference.PutBytes(value, value_size, 187 | &this->listener_); 188 | this->get_bytes_button_->setEnabled(false); 189 | this->put_bytes_button_->setEnabled(false); 190 | break; 191 | } 192 | default: { 193 | break; 194 | } 195 | } 196 | }); 197 | this->addChild(put_bytes_button_); 198 | 199 | // Create the close app menu item. 200 | auto closeAppItem = MenuItemImage::create( 201 | "CloseNormal.png", "CloseSelected.png", 202 | CC_CALLBACK_1(FirebaseScene::menuCloseAppCallback, this)); 203 | closeAppItem->setContentSize(cocos2d::Size(25, 25)); 204 | // Position the close app menu item on the top-right corner of the screen. 205 | closeAppItem->setPosition(cocos2d::Vec2( 206 | origin.x + visibleSize.width - closeAppItem->getContentSize().width / 2, 207 | origin.y + visibleSize.height - 208 | closeAppItem->getContentSize().height / 2)); 209 | 210 | // Create the Menu for touch handling. 211 | auto menu = Menu::create(closeAppItem, NULL); 212 | menu->setPosition(cocos2d::Vec2::ZERO); 213 | this->addChild(menu, 1); 214 | 215 | state_ = kStateInitialize; 216 | 217 | // Schedule the update method for this scene. 218 | this->scheduleUpdate(); 219 | 220 | return true; 221 | } 222 | 223 | FirebaseStorageScene::State FirebaseStorageScene::updateInitialize() { 224 | firebase::Future initialize_future = 225 | initializer_.InitializeLastResult(); 226 | if (initialize_future.status() != firebase::kFutureStatusComplete) { 227 | return kStateInitialize; 228 | } 229 | if (initialize_future.error() != 0) { 230 | logMessage("Failed to initialize Firebase libraries: %s", 231 | initialize_future.error_message()); 232 | return kStateRun; 233 | } 234 | logMessage("Successfully initialized Firebase Auth and Firebase Storage."); 235 | auth_->SignInAnonymously(); 236 | return kStateLogin; 237 | } 238 | 239 | FirebaseStorageScene::State FirebaseStorageScene::updateLogin() { 240 | // Sign in using Auth before accessing the storage. 241 | // 242 | // The default Storage permissions allow anonymous user access. However, 243 | // Firebase Auth does not allow anonymous user login by default. This setting 244 | // can be changed in the Auth settings page for your project in the Firebase 245 | // Console under the "Sign-In Method" tab. 246 | firebase::Future sign_in_future = 247 | auth_->SignInAnonymouslyLastResult(); 248 | if (sign_in_future.status() != firebase::kFutureStatusComplete) { 249 | return kStateLogin; 250 | } 251 | if (sign_in_future.error() != firebase::auth::kAuthErrorNone) { 252 | logMessage("ERROR: Could not sign in anonymously. Error %d: %s", 253 | sign_in_future.error(), sign_in_future.error_message()); 254 | logMessage( 255 | "Ensure your application has the Anonymous sign-in provider enabled in " 256 | "the Firebase Console."); 257 | return kStateRun; 258 | } 259 | logMessage("Auth: Signed in anonymously."); 260 | get_bytes_button_->setEnabled(true); 261 | put_bytes_button_->setEnabled(true); 262 | return kStateRun; 263 | } 264 | 265 | FirebaseStorageScene::State FirebaseStorageScene::updateRun() { 266 | if (get_bytes_future_.status() == firebase::kFutureStatusComplete) { 267 | if (get_bytes_future_.error() == firebase::storage::kErrorNone) { 268 | logMessage("GetBytes complete"); 269 | const size_t* length = get_bytes_future_.result(); 270 | logMessage("Got %i bytes: %s", static_cast(*length), byte_buffer_); 271 | } else { 272 | logMessage("ERROR: Could not get bytes. Error %d: %s", 273 | get_bytes_future_.error(), get_bytes_future_.error_message()); 274 | } 275 | get_bytes_button_->setEnabled(true); 276 | put_bytes_button_->setEnabled(true); 277 | get_bytes_future_.Release(); 278 | } 279 | if (put_bytes_future_.status() == firebase::kFutureStatusComplete) { 280 | if (put_bytes_future_.error() == firebase::storage::kErrorNone) { 281 | logMessage("PutBytes complete."); 282 | const firebase::storage::Metadata* metadata = put_bytes_future_.result(); 283 | logMessage("Put %i bytes", static_cast(metadata->size_bytes())); 284 | } else { 285 | logMessage("ERROR: Could not put bytes. Error %d: %s", 286 | put_bytes_future_.error(), put_bytes_future_.error_message()); 287 | } 288 | get_bytes_button_->setEnabled(true); 289 | put_bytes_button_->setEnabled(true); 290 | put_bytes_future_.Release(); 291 | } 292 | return kStateRun; 293 | } 294 | 295 | // Called automatically every frame. The update is scheduled in `init()`. 296 | void FirebaseStorageScene::update(float /*delta*/) { 297 | switch (state_) { 298 | case kStateInitialize: state_ = updateInitialize(); break; 299 | case kStateLogin: state_ = updateLogin(); break; 300 | case kStateRun: state_ = updateRun(); break; 301 | default: assert(0); 302 | } 303 | } 304 | 305 | /// Handles the user tapping on the close app menu item. 306 | void FirebaseStorageScene::menuCloseAppCallback(Ref* pSender) { 307 | CCLOG("Cleaning up Storage C++ resources."); 308 | 309 | // Close the cocos2d-x game scene and quit the application. 310 | Director::getInstance()->end(); 311 | 312 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 313 | exit(0); 314 | #endif 315 | } 316 | -------------------------------------------------------------------------------- /database/Classes/FirebaseDatabaseScene.cpp: -------------------------------------------------------------------------------- 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 "FirebaseDatabaseScene.h" 22 | 23 | #include 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 28 | #include "platform/android/jni/JniHelper.h" 29 | #endif 30 | 31 | #include "FirebaseCocos.h" 32 | #include "firebase/auth.h" 33 | #include "firebase/database.h" 34 | #include "firebase/future.h" 35 | 36 | USING_NS_CC; 37 | 38 | /// Padding for the UI elements. 39 | static const float kUIElementPadding = 10.0; 40 | 41 | /// Placeholder labels for the text fields. 42 | static const char* kKeyPlaceholderText = "Key"; 43 | static const char* kValuePlaceholderText = "Value"; 44 | 45 | static const char* kTestAppData = "test_app_data"; 46 | 47 | static void logDataSnapshot(FirebaseDatabaseScene* scene, 48 | const firebase::database::DataSnapshot& snapshot) { 49 | const firebase::Variant& value_variant = snapshot.value(); 50 | const char* key = snapshot.key(); 51 | switch (value_variant.type()) { 52 | case firebase::Variant::kTypeNull: { 53 | scene->logMessage("key: `%s`, value: null", key); 54 | break; 55 | } 56 | case firebase::Variant::kTypeInt64: { 57 | int64_t value = value_variant.int64_value(); 58 | scene->logMessage("key: \"%s\", value: %lli", key, value); 59 | break; 60 | } 61 | case firebase::Variant::kTypeDouble: { 62 | double value = value_variant.double_value(); 63 | scene->logMessage("key: \"%s\", value: %f", key, value); 64 | break; 65 | } 66 | case firebase::Variant::kTypeBool: { 67 | bool value = value_variant.bool_value(); 68 | scene->logMessage("key: \"%s\", value: %s", key, 69 | value ? "true" : "false"); 70 | break; 71 | } 72 | case firebase::Variant::kTypeMutableString: 73 | case firebase::Variant::kTypeStaticString: { 74 | const char* value = value_variant.string_value(); 75 | scene->logMessage("key: \"%s\", value: \"%s\"", key, 76 | value ? value : ""); 77 | break; 78 | } 79 | default: { 80 | scene->logMessage("ERROR: This sample only supports scalar variants."); 81 | } 82 | } 83 | } 84 | 85 | // An example of a ValueListener object. This specific version will 86 | // simply log every value it sees, and store them in a list so we can 87 | // confirm that all values were received. 88 | class SampleValueListener : public firebase::database::ValueListener { 89 | public: 90 | SampleValueListener(FirebaseDatabaseScene* scene) : scene_(scene) {}; 91 | 92 | void OnValueChanged( 93 | const firebase::database::DataSnapshot& snapshot) override { 94 | scene_->logMessage("ValueListener::OnValueChanged"); 95 | logDataSnapshot(scene_, snapshot); 96 | } 97 | 98 | void OnCancelled(const firebase::database::Error& error_code, 99 | const char* error_message) override { 100 | scene_->logMessage("ERROR: SampleValueListener canceled: %d: %s", 101 | error_code, error_message); 102 | } 103 | 104 | private: 105 | FirebaseDatabaseScene* scene_; 106 | }; 107 | 108 | /// Creates the Firebase scene. 109 | Scene* CreateFirebaseScene() { 110 | return FirebaseDatabaseScene::createScene(); 111 | } 112 | 113 | /// Creates the FirebaseDatabaseScene. 114 | Scene* FirebaseDatabaseScene::createScene() { 115 | // Create the scene. 116 | auto scene = Scene::create(); 117 | 118 | // Create the layer. 119 | auto layer = FirebaseDatabaseScene::create(); 120 | 121 | // Add the layer to the scene. 122 | scene->addChild(layer); 123 | 124 | return scene; 125 | } 126 | 127 | /// Initializes the FirebaseScene. 128 | bool FirebaseDatabaseScene::init() { 129 | if (!Layer::init()) { 130 | return false; 131 | } 132 | 133 | auto visibleSize = Director::getInstance()->getVisibleSize(); 134 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 135 | 136 | // Create the Firebase label. 137 | auto firebaseLabel = 138 | Label::createWithTTF("Firebase Database", "fonts/Marker Felt.ttf", 20); 139 | nextYPosition = 140 | origin.y + visibleSize.height - firebaseLabel->getContentSize().height; 141 | firebaseLabel->setPosition( 142 | cocos2d::Vec2(origin.x + visibleSize.width / 2, nextYPosition)); 143 | this->addChild(firebaseLabel, 1); 144 | 145 | const float scrollViewYPosition = nextYPosition - 146 | firebaseLabel->getContentSize().height - 147 | kUIElementPadding * 2; 148 | // Create the ScrollView on the Cocos2d thread. 149 | cocos2d::Director::getInstance() 150 | ->getScheduler() 151 | ->performFunctionInCocosThread( 152 | [=]() { this->createScrollView(scrollViewYPosition); }); 153 | 154 | // Use ModuleInitializer to initialize both Auth and Database, ensuring no 155 | // dependencies are missing. 156 | void* initialize_targets[] = {&auth_, &database_}; 157 | 158 | CCLOG("Initializing the Database with Firebase API."); 159 | const firebase::ModuleInitializer::InitializerFn initializers[] = { 160 | [](firebase::App* app, void* data) { 161 | // this->logMessage("Attempt to initialize Firebase Auth."); 162 | void** targets = reinterpret_cast(data); 163 | firebase::InitResult result; 164 | *reinterpret_cast(targets[0]) = 165 | firebase::auth::Auth::GetAuth(app, &result); 166 | return result; 167 | }, 168 | [](firebase::App* app, void* data) { 169 | // this->logMessage("Attempt to initialize Firebase Database."); 170 | void** targets = reinterpret_cast(data); 171 | firebase::InitResult result; 172 | *reinterpret_cast(targets[1]) = 173 | firebase::database::Database::GetInstance(app, &result); 174 | return result; 175 | }}; 176 | 177 | // There are two ways to track long running operations: (1) retrieve the 178 | // future using a LastResult function or (2) Cache the future manually. 179 | // 180 | // Here we use method 1: the future is not cached but will be later retrieved 181 | // using SetValueLastResult. Which method is best for your app depends on 182 | // your use case. 183 | initializer_.Initialize( 184 | firebase::App::GetInstance(), initialize_targets, initializers, 185 | sizeof(initializers) / sizeof(initializers[0])); 186 | 187 | logMessage("Created the Database %x class for the Firebase app.", 188 | static_cast(reinterpret_cast(database_))); 189 | 190 | key_text_field_ = createTextField(kKeyPlaceholderText); 191 | this->addChild(key_text_field_); 192 | 193 | value_text_field_ = createTextField(kValuePlaceholderText); 194 | this->addChild(value_text_field_); 195 | 196 | add_listener_button_ = createButton(false, "Add Listener"); 197 | add_listener_button_->addTouchEventListener( 198 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 199 | switch (type) { 200 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 201 | const char* key = key_text_field_->getString().c_str(); 202 | firebase::database::DatabaseReference reference = 203 | this->database_->GetReference(kTestAppData).Child(key); 204 | this->logMessage("Adding ValueListener to key `%s`.", key); 205 | // The SampleValueListener will respond to changes in this entry's 206 | // value. Changes can be made by other instances of this sample app 207 | // or in the Firebase Console. 208 | reference.AddValueListener(new SampleValueListener(this)); 209 | break; 210 | } 211 | default: { 212 | break; 213 | } 214 | } 215 | }); 216 | this->addChild(add_listener_button_); 217 | 218 | query_button_ = createButton(false, "Query"); 219 | query_button_->addTouchEventListener( 220 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 221 | switch (type) { 222 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 223 | const char* key = key_text_field_->getString().c_str(); 224 | firebase::database::DatabaseReference reference = 225 | this->database_->GetReference(kTestAppData).Child(key); 226 | this->logMessage("Querying key `%s`.", key); 227 | // There are two ways to track long running operations: 228 | // (1) retrieve the future using a LastResult function or (2) Cache 229 | // the future manually. 230 | // 231 | // Here (and below in the set_button_) we use method 2: caching the 232 | // future. Which method is best for your app depends on your use 233 | // case. 234 | query_future_ = reference.GetValue(); 235 | this->query_button_->setEnabled(false); 236 | this->set_button_->setEnabled(false); 237 | break; 238 | } 239 | default: { 240 | break; 241 | } 242 | } 243 | }); 244 | this->addChild(query_button_); 245 | 246 | set_button_ = createButton(false, "Set"); 247 | set_button_->addTouchEventListener( 248 | [this](Ref* /*sender*/, cocos2d::ui::Widget::TouchEventType type) { 249 | switch (type) { 250 | case cocos2d::ui::Widget::TouchEventType::ENDED: { 251 | const char* key = key_text_field_->getString().c_str(); 252 | const char* value = value_text_field_->getString().c_str(); 253 | firebase::database::DatabaseReference reference = 254 | this->database_->GetReference(kTestAppData).Child(key); 255 | this->logMessage("Setting key `%s` to `%s`.", key, value); 256 | this->set_future_ = reference.SetValue(value); 257 | this->query_button_->setEnabled(false); 258 | this->set_button_->setEnabled(false); 259 | break; 260 | } 261 | default: { 262 | break; 263 | } 264 | } 265 | }); 266 | this->addChild(set_button_); 267 | 268 | // Create the close app menu item. 269 | auto closeAppItem = MenuItemImage::create( 270 | "CloseNormal.png", "CloseSelected.png", 271 | CC_CALLBACK_1(FirebaseScene::menuCloseAppCallback, this)); 272 | closeAppItem->setContentSize(cocos2d::Size(25, 25)); 273 | // Position the close app menu item on the top-right corner of the screen. 274 | closeAppItem->setPosition(cocos2d::Vec2( 275 | origin.x + visibleSize.width - closeAppItem->getContentSize().width / 2, 276 | origin.y + visibleSize.height - 277 | closeAppItem->getContentSize().height / 2)); 278 | 279 | // Create the Menu for touch handling. 280 | auto menu = Menu::create(closeAppItem, NULL); 281 | menu->setPosition(cocos2d::Vec2::ZERO); 282 | this->addChild(menu, 1); 283 | 284 | state_ = kStateInitialize; 285 | 286 | // Schedule the update method for this scene. 287 | this->scheduleUpdate(); 288 | 289 | return true; 290 | } 291 | 292 | FirebaseDatabaseScene::State FirebaseDatabaseScene::updateInitialize() { 293 | firebase::Future initialize_future = 294 | initializer_.InitializeLastResult(); 295 | if (initialize_future.status() != firebase::kFutureStatusComplete) { 296 | return kStateInitialize; 297 | } 298 | if (initialize_future.error() != 0) { 299 | logMessage("Failed to initialize Firebase libraries: %s", 300 | initialize_future.error_message()); 301 | return kStateRun; 302 | } 303 | logMessage("Successfully initialized Firebase Auth and Firebase Database."); 304 | auth_->SignInAnonymously(); 305 | return kStateLogin; 306 | } 307 | 308 | FirebaseDatabaseScene::State FirebaseDatabaseScene::updateLogin() { 309 | // Sign in using Auth before accessing the database. 310 | // 311 | // The default Database permissions allow anonymous user access. However, 312 | // Firebase Auth does not allow anonymous user login by default. This setting 313 | // can be changed in the Auth settings page for your project in the Firebase 314 | // Console under the "Sign-In Method" tab. 315 | firebase::Future sign_in_future = 316 | auth_->SignInAnonymouslyLastResult(); 317 | if (sign_in_future.status() != firebase::kFutureStatusComplete) { 318 | return kStateLogin; 319 | } 320 | if (sign_in_future.error() != firebase::auth::kAuthErrorNone) { 321 | logMessage("ERROR: Could not sign in anonymously. Error %d: %s", 322 | sign_in_future.error(), sign_in_future.error_message()); 323 | logMessage( 324 | "Ensure your application has the Anonymous sign-in provider enabled in " 325 | "the Firebase Console."); 326 | return kStateRun; 327 | } 328 | logMessage("Auth: Signed in anonymously."); 329 | add_listener_button_->setEnabled(true); 330 | query_button_->setEnabled(true); 331 | set_button_->setEnabled(true); 332 | return kStateRun; 333 | } 334 | 335 | FirebaseDatabaseScene::State FirebaseDatabaseScene::updateRun() { 336 | if (query_future_.status() == firebase::kFutureStatusComplete) { 337 | if (query_future_.error() == firebase::database::kErrorNone) { 338 | logMessage("Query complete"); 339 | const firebase::database::DataSnapshot* snapshot = query_future_.result(); 340 | logDataSnapshot(this, *snapshot); 341 | } else { 342 | logMessage("ERROR: Could not query value. Error %d: %s", 343 | query_future_.error(), query_future_.error_message()); 344 | } 345 | query_button_->setEnabled(true); 346 | set_button_->setEnabled(true); 347 | query_future_.Release(); 348 | } 349 | if (set_future_.status() == firebase::kFutureStatusComplete) { 350 | if (set_future_.error() == firebase::database::kErrorNone) { 351 | logMessage("Database updated."); 352 | } else { 353 | logMessage("ERROR: Could not set value. Error %d: %s", 354 | set_future_.error(), set_future_.error_message()); 355 | } 356 | query_button_->setEnabled(true); 357 | set_button_->setEnabled(true); 358 | set_future_.Release(); 359 | } 360 | return kStateRun; 361 | } 362 | 363 | // Called automatically every frame. The update is scheduled in `init()`. 364 | void FirebaseDatabaseScene::update(float /*delta*/) { 365 | switch (state_) { 366 | case kStateInitialize: state_ = updateInitialize(); break; 367 | case kStateLogin: state_ = updateLogin(); break; 368 | case kStateRun: state_ = updateRun(); break; 369 | default: assert(0); 370 | } 371 | } 372 | 373 | /// Handles the user tapping on the close app menu item. 374 | void FirebaseDatabaseScene::menuCloseAppCallback(Ref* pSender) { 375 | CCLOG("Cleaning up Database C++ resources."); 376 | 377 | // Close the cocos2d-x game scene and quit the application. 378 | Director::getInstance()->end(); 379 | 380 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 381 | exit(0); 382 | #endif 383 | } 384 | -------------------------------------------------------------------------------- /setup_firebase_sample.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # coding=utf-8 3 | 4 | # Copyright 2017 Google Inc. All rights reserved. 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to 8 | # deal in the Software without restriction, including without limitation the 9 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | # sell copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | """Sets up the Firebase cocos2d-x sample project. 24 | 25 | For help: 26 | 27 | python setup_firebase_sample.py --help 28 | 29 | Run the script: 30 | 31 | python setup_firebase_sample.py FIREBASE_FEATURE 32 | 33 | Where FIREBASE_FEATURE is one of the following: 34 | 35 | AdMob, Analytics, Auth, Database, Invites, Messaging, Remote_Config or Storage 36 | """ 37 | 38 | import argparse 39 | import fileinput 40 | import glob 41 | import logging 42 | import os 43 | import platform 44 | import shutil 45 | import sys 46 | import urllib 47 | import zipfile 48 | 49 | # The setup_firebase_sample.py script directory. 50 | ROOT_DIRECTORY = os.path.dirname(os.path.abspath(__file__)) 51 | # The Firebase SDK download URL. 52 | FIREBASE_SDK_URL = "http://firebase.google.com/download/cpp" 53 | # The cocos2d-x GitHub release download URL. 54 | COCOS2DX_GITHUB_URL = "https://github.com/cocos2d/cocos2d-x/archive/cocos2d-x-3.14.1.zip" 55 | # The iOS project directory. 56 | IOS_PROJECT_DIR = os.path.join(ROOT_DIRECTORY, "sample_project/proj.ios_mac") 57 | # The iOS project.pbxproj file. 58 | IOS_PROJECT_FILE = os.path.join(IOS_PROJECT_DIR, 59 | "HelloCpp.xcodeproj/project.pbxproj") 60 | # The Android project directory. 61 | ANDROID_PROJECT_DIR = os.path.join(ROOT_DIRECTORY, 62 | "sample_project/proj.android-studio") 63 | # The Android.mk file. 64 | ANDROID_MAKEFILE = os.path.join(ANDROID_PROJECT_DIR, "app/jni/Android.mk") 65 | # The Libs directory for the cocos2d-x sample project. This is where the 66 | # Firebase SDK is located. 67 | LIBS_DIR = os.path.join(ROOT_DIRECTORY, "sample_project/Libs") 68 | # The Firebase features passed by the caller of this script. 69 | FEATURE_ARGS_ARRAY = [] 70 | # The Firebase features supported by this script. 71 | FIREBASE_FEATURES_ARRAY = [ 72 | "AdMob", 73 | "Analytics", 74 | "Auth", 75 | "Database", 76 | "Invites", 77 | "Messaging", 78 | "Remote_Config", 79 | "Storage", 80 | ] 81 | # The path to the Firebase SDK to use. This is optional, if left blank the most 82 | # recent release will be downloaded and used. 83 | FIREBASE_SDK_PATH = None 84 | # The path to the Cocos2D-x library to use. This is optional, if left blank the 85 | # most recent release will be downloaded and used. 86 | COCOS2DX_LIBRARY_PATH = None 87 | 88 | 89 | def add_cocos2dx_library(): 90 | """Adds the cocos2d-x library to the sample project. 91 | 92 | Creates the sample project directory, adds the cocos2d-x library to the 93 | sample project directory, runs the cocos2d/download-deps.py script to pull 94 | in the third-party dependencies, and creates the .cocos-project.json file 95 | which is required for compiling the Android app. 96 | 97 | Raises: 98 | IOError: An error occurred retrieving the zip file. 99 | zipfile.BadZipfile: An error occurred because the zip file is not valid. 100 | """ 101 | logging.info("Adding the cocos2d-x library (this may take a bit)...") 102 | sample_project_dir = os.path.join(ROOT_DIRECTORY, "sample_project") 103 | os.makedirs(sample_project_dir) 104 | os.chdir(sample_project_dir) 105 | try: 106 | url = COCOS2DX_LIBRARY_PATH or COCOS2DX_GITHUB_URL 107 | zip_name = "cocos2dx.zip" 108 | filename, headers = urllib.urlretrieve(url, zip_name) 109 | zip_file = zipfile.ZipFile(filename) 110 | zip_file.extractall(sample_project_dir) 111 | zip_file.close() 112 | for file in os.listdir("."): 113 | # The extracted folder name is prefixed with "cocos2d-x-cocos2d-x-##." 114 | if file.startswith("cocos2d-x-cocos2d-x-"): 115 | os.rename(file, "cocos2d") 116 | break 117 | os.remove(os.path.join(sample_project_dir, zip_name)) 118 | except IOError as e: 119 | logging.exception("IOError: [Errno %d] %s: in %s", e.errno, e.strerror, 120 | sys._getframe().f_code.co_name) 121 | exit() 122 | except zipfile.BadZipfile, e: 123 | logging.exception("%s is not a valid zip file in %s.", COCOS2DX_GITHUB_URL, 124 | sys._getframe().f_code.co_name) 125 | exit() 126 | # Download the third-party dependencies into the cocos2d library. 127 | os.system("python cocos2d/download-deps.py -r yes") 128 | os.chdir(ROOT_DIRECTORY) 129 | # Create the .cocos-project.json file. This is a hidden file that declares the 130 | # project type and is required for building and running the Android app. For 131 | # this sample project, the project type is "cpp." 132 | file = open("sample_project/.cocos-project.json", "w") 133 | file.write('{"project_type": "cpp"}') 134 | file.close() 135 | logging.info("Finished adding the cocos2d-x library to the sample project.") 136 | 137 | 138 | def retrieve_latest_firebase_sdk(): 139 | """Adds the latest version of the Firebase SDK to the sample project. 140 | 141 | Raises: 142 | IOError: An error occurred retrieving the zip file. 143 | zipfile.BadZipfile: An error occurred because the zip file is not valid. 144 | """ 145 | logging.info("Adding the Firebase SDK (this may take a bit)...") 146 | try: 147 | url = FIREBASE_SDK_PATH or FIREBASE_SDK_URL 148 | zip_name = "firebase_cpp_sdk.zip" 149 | filename, headers = urllib.urlretrieve(url, zip_name) 150 | zip_file = zipfile.ZipFile(filename) 151 | zip_file.extractall(LIBS_DIR) 152 | zip_file.close() 153 | os.remove(os.path.join(ROOT_DIRECTORY, zip_name)) 154 | except IOError as e: 155 | logging.exception("IOError: [Errno %d] %s: in %s", e.errno, e.strerror, 156 | sys._getframe().f_code.co_name) 157 | exit() 158 | except zipfile.BadZipfile, e: 159 | logging.exception("%s is not a valid zip file in %s.", FIREBASE_SDK_URL, 160 | sys._getframe().f_code.co_name) 161 | exit() 162 | logging.info( 163 | "Finished adding the Firebase SDK to the sample project's Libs directory") 164 | 165 | 166 | def add_cpp_default_template(): 167 | """Adds the C++ default project template to the sample project directory. 168 | 169 | Raises: 170 | IOError: An error occurred copying the C++ default project template to the 171 | sample project directory. 172 | """ 173 | cpp_default_template_dir = os.path.join( 174 | ROOT_DIRECTORY, "sample_project/cocos2d/templates/cpp-template-default") 175 | dst_dir = os.path.join(ROOT_DIRECTORY, "sample_project") 176 | try: 177 | for item in os.listdir(cpp_default_template_dir): 178 | src = os.path.join(cpp_default_template_dir, item) 179 | dst = os.path.join(dst_dir, item) 180 | if os.path.isdir(src): 181 | shutil.copytree(src, dst) 182 | else: 183 | shutil.copy(src, dst) 184 | except IOError as e: 185 | logging.exception("IOError: [Errno %d] %s: in %s", e.errno, e.strerror, 186 | sys._getframe().f_code.co_name) 187 | exit() 188 | logging.info( 189 | "Added the C++ default project template to the sample project directory.") 190 | 191 | 192 | def add_project_template_files(): 193 | """Adds the project template files to the sample project. 194 | 195 | Raises: 196 | IOError: An error occurred copying the project template files. 197 | """ 198 | firebase_feature = FEATURE_ARGS_ARRAY[0].lower() 199 | common_ios_project_file = os.path.join( 200 | ROOT_DIRECTORY, "common/project_template_files/project.pbxproj") 201 | project_ios_project_file = os.path.join( 202 | ROOT_DIRECTORY, firebase_feature, "project_files/project.pbxproj") 203 | common_android_makefile = os.path.join( 204 | ROOT_DIRECTORY, "common/project_template_files/Android.mk") 205 | project_android_makefile = os.path.join( 206 | ROOT_DIRECTORY, firebase_feature, "project_files/Android.mk") 207 | ios_dst_dir = os.path.join(IOS_PROJECT_DIR, "HelloCpp.xcodeproj") 208 | android_dst_dir = os.path.join(ANDROID_PROJECT_DIR, "app/jni") 209 | try: 210 | if os.path.isfile(project_ios_project_file): 211 | shutil.copy(project_ios_project_file, ios_dst_dir) 212 | else: 213 | shutil.copy(common_ios_project_file, ios_dst_dir) 214 | if os.path.isfile(project_android_makefile): 215 | shutil.copy(project_android_makefile, android_dst_dir) 216 | else: 217 | shutil.copy(common_android_makefile, android_dst_dir) 218 | except IOError as e: 219 | logging.exception("IOError: [Errno %d] %s: in %s", e.errno, e.strerror, 220 | sys._getframe().f_code.co_name) 221 | exit() 222 | logging.info("Added the project template files to the sample project.") 223 | 224 | 225 | def update_project_file(filename): 226 | """Updates the given project file. 227 | 228 | Replaces "{FIREBASE_FEATURE}" placeholders in the project file with the 229 | Firebase feature passed to this script. Specifying the feature ensures that 230 | the proper frameworks and implementation files are referenced in the project 231 | file. 232 | """ 233 | firebase_feature = FEATURE_ARGS_ARRAY[0].lower() 234 | firebase_feature_camelcase = FEATURE_ARGS_ARRAY[0].replace("_", "") 235 | for line in fileinput.input(filename, inplace=True): 236 | if "{FIREBASE_FEATURE}" in line: 237 | print line.replace("{FIREBASE_FEATURE}", firebase_feature).replace("\n", 238 | "") 239 | elif "{FIREBASE_FEATURE_CAMELCASE}" in line: 240 | print line.replace("{FIREBASE_FEATURE_CAMELCASE}", 241 | firebase_feature_camelcase).replace("\n", "") 242 | else: 243 | print line.replace("\n", "") 244 | 245 | 246 | def update_ios_project_file(): 247 | """Updates the iOS project.pbxproj file.""" 248 | update_project_file(IOS_PROJECT_FILE) 249 | logging.info("Updated the iOS project.pbxproj file.") 250 | 251 | 252 | def update_android_makefile(): 253 | """Updates the Android.mk file.""" 254 | update_project_file(ANDROID_MAKEFILE) 255 | logging.info("Updated the Android.mk file.") 256 | 257 | 258 | def add_resource_files(): 259 | """Adds the resource files to the sample project's Resources directory. 260 | 261 | Raises: 262 | IOError: An error occurred copying the resource files. 263 | """ 264 | common_resources_dir = os.path.join(ROOT_DIRECTORY, "common/Resources") 265 | dst_dir = os.path.join(ROOT_DIRECTORY, "sample_project/Resources") 266 | try: 267 | common_resources_files = os.listdir(common_resources_dir) 268 | for file_name in common_resources_files: 269 | full_file_name = os.path.join(common_resources_dir, file_name) 270 | if os.path.isfile(full_file_name): 271 | shutil.copy(full_file_name, dst_dir) 272 | except IOError as e: 273 | logging.exception("IOError: [Errno %d] %s: in %s", e.errno, e.strerror, 274 | sys._getframe().f_code.co_name) 275 | exit() 276 | logging.info("Added files to the sample project's Resources directory.") 277 | 278 | 279 | def add_class_files(): 280 | """Adds the C++ class files to the sample project's Classes directory. 281 | 282 | Raises: 283 | IOError: An error occurred copying the class files. 284 | """ 285 | firebase_feature = FEATURE_ARGS_ARRAY[0].lower() 286 | common_classes_dir = os.path.join(ROOT_DIRECTORY, "common/Classes") 287 | third_party_classes_glob = os.path.join( 288 | ROOT_DIRECTORY, "third_party/cocos2dx/common/Classes/*") 289 | feature_classes_dir = os.path.join(ROOT_DIRECTORY, firebase_feature, 290 | "Classes") 291 | dst_dir = os.path.join(ROOT_DIRECTORY, "sample_project/Classes") 292 | try: 293 | shutil.rmtree(dst_dir) 294 | shutil.copytree(common_classes_dir, dst_dir) 295 | for file in glob.glob(third_party_classes_glob): 296 | shutil.copy(file, dst_dir) 297 | feature_classes_files = os.listdir(feature_classes_dir) 298 | for file_name in feature_classes_files: 299 | full_file_name = os.path.join(feature_classes_dir, file_name) 300 | if os.path.isfile(full_file_name): 301 | shutil.copy(full_file_name, dst_dir) 302 | except IOError as e: 303 | logging.exception("IOError: [Errno %d] %s: in %s", e.errno, e.strerror, 304 | sys._getframe().f_code.co_name) 305 | exit() 306 | logging.info("Added files to the sample project's Classes directory.") 307 | 308 | 309 | def add_android_files(): 310 | """Adds the Android gradle files to the sample project. 311 | 312 | Raises: 313 | IOError: An error occurred copying the Android files. 314 | """ 315 | firebase_feature = FEATURE_ARGS_ARRAY[0].lower() 316 | project_gradle_file = os.path.join(ROOT_DIRECTORY, firebase_feature, 317 | "build.gradle") 318 | app_gradle_file = os.path.join(ROOT_DIRECTORY, firebase_feature, 319 | "app/build.gradle") 320 | try: 321 | shutil.copy(project_gradle_file, ANDROID_PROJECT_DIR) 322 | shutil.copy(app_gradle_file, os.path.join(ANDROID_PROJECT_DIR, "app")) 323 | except IOError as e: 324 | logging.exception("IOError: [Errno %d] %s: in %s", e.errno, e.strerror, 325 | sys._getframe().f_code.co_name) 326 | exit() 327 | logging.info("Added the Android gradle files to the sample project.") 328 | 329 | 330 | def run_pod_install(): 331 | """Installs the Firebase pods in the iOS project. 332 | 333 | This function is only run on Mac (Darwin). 334 | 335 | Raises: 336 | IOError: An error occurred copying the Podfile. 337 | """ 338 | logging.info("Running pod install...") 339 | firebase_feature = FEATURE_ARGS_ARRAY[0].lower() 340 | podfile = os.path.join(ROOT_DIRECTORY, firebase_feature, "Podfile") 341 | try: 342 | shutil.copy(podfile, IOS_PROJECT_DIR) 343 | except IOError as e: 344 | logging.exception("IOError: [Errno %d] %s: in %s", e.errno, e.strerror, 345 | sys._getframe().f_code.co_name) 346 | exit() 347 | os.chdir(IOS_PROJECT_DIR) 348 | os.system("pod install") 349 | os.chdir(ROOT_DIRECTORY) 350 | logging.info("Finished running pod install.") 351 | 352 | 353 | def check_valid_arguments(): 354 | """Checks if the user passed valid arguments to the script.""" 355 | parser = argparse.ArgumentParser( 356 | description="This script sets up the cocos2d-x sample project for " 357 | "Firebase C++.") 358 | parser.add_argument( 359 | "feature", 360 | metavar="FIREBASE_FEATURE", 361 | nargs=1, 362 | help="The Firebase feature must be one of the following: " 363 | "AdMob, Analytics, Auth, Invites, Messaging, or Remote_Config") 364 | parser.add_argument( 365 | "--firebase_sdk", 366 | action='store', 367 | const=None, 368 | metavar="FIREBASE_SDK", 369 | help="The path to the Firebase SDK zip file. If left blank, the most " 370 | "recent release will be downloaded and used.") 371 | parser.add_argument( 372 | "--cocos2dx_library", 373 | action='store', 374 | const=None, 375 | metavar="COCOS2DX_LIBRARY", 376 | help="The path to Cocos2d-x library zip file. If left blank, the most " 377 | "recent release will be downloaded and used.") 378 | args = parser.parse_args() 379 | for feature in args.feature: 380 | feature_str = str(feature) 381 | if not feature_str in FIREBASE_FEATURES_ARRAY: 382 | return False 383 | FEATURE_ARGS_ARRAY.append(feature_str) 384 | 385 | global FIREBASE_SDK_PATH 386 | FIREBASE_SDK_PATH = args.firebase_sdk 387 | 388 | global COCOS2DX_LIBRARY_PATH 389 | COCOS2DX_LIBRARY_PATH = args.cocos2dx_library 390 | 391 | return True 392 | 393 | 394 | def main(): 395 | """The main function.""" 396 | # The root logger of the hierarchy. 397 | logger = logging.getLogger() 398 | logger.setLevel(logging.DEBUG) 399 | 400 | # Add a StreamHandler to log to stdout. 401 | stream_handler = logging.StreamHandler(sys.stdout) 402 | stream_handler.setLevel(logging.DEBUG) 403 | formatter = logging.Formatter( 404 | "%(asctime)s - %(name)s - %(levelname)s - %(message)s") 405 | stream_handler.setFormatter(formatter) 406 | logger.addHandler(stream_handler) 407 | 408 | if not check_valid_arguments(): 409 | logging.info( 410 | "This script takes one argument, the name of the Firebase feature you " 411 | "want to use for the cocos2d-x sample project. Valid values are:") 412 | logging.info(FIREBASE_FEATURES_ARRAY) 413 | exit() 414 | 415 | add_cocos2dx_library() 416 | retrieve_latest_firebase_sdk() 417 | add_cpp_default_template() 418 | add_project_template_files() 419 | update_ios_project_file() 420 | update_android_makefile() 421 | add_resource_files() 422 | add_class_files() 423 | add_android_files() 424 | if platform.system() == "Darwin": 425 | run_pod_install() 426 | logging.info("Finished setting up %s.", FEATURE_ARGS_ARRAY) 427 | 428 | 429 | # Check to see if this script is being called directly. 430 | if __name__ == "__main__": 431 | exit(main()) 432 | -------------------------------------------------------------------------------- /admob/Classes/FirebaseAdMobScene.cpp: -------------------------------------------------------------------------------- 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 "FirebaseAdMobScene.h" 22 | 23 | #include 24 | 25 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 26 | #include 27 | #include 28 | #include "platform/android/jni/JniHelper.h" 29 | #endif 30 | 31 | #include "FirebaseCocos.h" 32 | #include "firebase/admob.h" 33 | 34 | USING_NS_CC; 35 | 36 | namespace rewarded_video = firebase::admob::rewarded_video; 37 | 38 | bool interstitialAdShown = false; 39 | bool rewardedVideoAdShown = false; 40 | 41 | /// Padding for the UI elements. 42 | static const float kUIElementPadding = 10.0; 43 | 44 | // The title text for the Firebase buttons. 45 | static const std::string kLoadAdViewText = "Load Banner"; 46 | static const std::string kShowAdViewText = "Show Banner"; 47 | static const std::string kHideAdViewText = "Hide Banner"; 48 | static const std::string kMoveAdViewText = "Move Banner"; 49 | static const std::string kLoadInterstitialText = "Load Interstitial"; 50 | static const std::string kShowInterstitialText = "Show Interstitial"; 51 | static const std::string kLoadRewardedVideoText = "Load Rewarded Video"; 52 | static const std::string kShowRewardedVideoText = "Show Rewarded Video"; 53 | 54 | /// The possible screen positions for the ad view. 55 | const int adViewPositions[6] = { 56 | firebase::admob::BannerView::kPositionTop, 57 | firebase::admob::BannerView::kPositionBottom, 58 | firebase::admob::BannerView::kPositionTopLeft, 59 | firebase::admob::BannerView::kPositionTopRight, 60 | firebase::admob::BannerView::kPositionBottomLeft, 61 | firebase::admob::BannerView::kPositionBottomRight}; 62 | 63 | /// The ad view screen positions mapped to std::strings. 64 | const std::string adViewPositionStrings[6] = {"top center", "bottom center", 65 | "top left", "top right", 66 | "bottom left", "bottom right"}; 67 | 68 | /// The size of the adViewPositions array. 69 | static const int adViewPositionsCount = 70 | sizeof(adViewPositions) / sizeof(adViewPositions[0]); 71 | 72 | /// The ad view screen position index. 73 | static int adViewPositionIndex = 0; 74 | 75 | // The AdMob app IDs. 76 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 77 | const char* kAdMobAppID = "ca-app-pub-3940256099942544~3347511713"; 78 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 79 | const char* kAdMobAppID = "ca-app-pub-3940256099942544~1458002511"; 80 | #else 81 | const char* kAdMobAppID = ""; 82 | #endif 83 | 84 | // These ad units are configured to always serve test ads. 85 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 86 | const char* kAdViewAdUnit = "ca-app-pub-3940256099942544/6300978111"; 87 | const char* kInterstitialAdUnit = "ca-app-pub-3940256099942544/1033173712"; 88 | const char* kRewardedVideoAdUnit = "ca-app-pub-3940256099942544/2888167318"; 89 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 90 | const char* kAdViewAdUnit = "ca-app-pub-3940256099942544/2934735716"; 91 | const char* kInterstitialAdUnit = "ca-app-pub-3940256099942544/4411468910"; 92 | const char* kRewardedVideoAdUnit = "ca-app-pub-3940256099942544/6386090517"; 93 | #else 94 | const char* kAdViewAdUnit = ""; 95 | const char* kInterstitialAdUnit = ""; 96 | const char* kRewardedVideoAdUnit = ""; 97 | #endif 98 | 99 | // The ad view's ad size. 100 | static const int kAdViewWidth = 320; 101 | static const int kAdViewHeight = 50; 102 | 103 | // Sample keywords to use in making the request. 104 | static const char* kKeywords[] = {"AdMob", "C++", "Fun"}; 105 | 106 | // Sample test device IDs to use in making the request. 107 | static const char* kTestDeviceIDs[] = {"2077ef9a63d2b398840261c8221a0c9b", 108 | "098fe087d987c9a878965454a65654d7"}; 109 | 110 | // Sample birthday value to use in making the request. 111 | static const int kBirthdayDay = 10; 112 | static const int kBirthdayMonth = 11; 113 | static const int kBirthdayYear = 1976; 114 | 115 | /// A simple listener that logs changes to an ad view. 116 | class LoggingAdViewListener : public firebase::admob::BannerView::Listener { 117 | public: 118 | LoggingAdViewListener(FirebaseScene* scene) : scene(scene) {} 119 | void OnPresentationStateChanged( 120 | firebase::admob::BannerView* adView, 121 | firebase::admob::BannerView::PresentationState state) override { 122 | scene->logMessage("The ad view's PresentationState has changed to %d.", 123 | state); 124 | } 125 | void OnBoundingBoxChanged(firebase::admob::BannerView* adView, 126 | firebase::admob::BoundingBox box) override { 127 | scene->logMessage( 128 | "The ad view's BoundingBox has changed to (x: %d, y: %d, width: %d, " 129 | "height %d).", 130 | box.x, box.y, box.width, box.height); 131 | } 132 | 133 | private: 134 | FirebaseScene* scene; 135 | }; 136 | 137 | /// A simple listener that logs changes to an InterstitialAd. 138 | class LoggingInterstitialAdListener 139 | : public firebase::admob::InterstitialAd::Listener { 140 | public: 141 | LoggingInterstitialAdListener(FirebaseScene* scene) : scene(scene) {} 142 | void OnPresentationStateChanged( 143 | firebase::admob::InterstitialAd* interstitialAd, 144 | firebase::admob::InterstitialAd::PresentationState state) override { 145 | scene->logMessage("InterstitialAd PresentationState has changed to %d.", 146 | state); 147 | } 148 | 149 | private: 150 | FirebaseScene* scene; 151 | }; 152 | 153 | /// A simple listener that logs changes to rewarded video state. 154 | class LoggingRewardedVideoListener : public rewarded_video::Listener { 155 | public: 156 | LoggingRewardedVideoListener(FirebaseScene* scene) : scene(scene) {} 157 | void OnRewarded(rewarded_video::RewardItem reward) override { 158 | scene->logMessage("Rewarding user with %f %s.", reward.amount, 159 | reward.reward_type.c_str()); 160 | } 161 | void OnPresentationStateChanged( 162 | rewarded_video::PresentationState state) override { 163 | scene->logMessage("Rewarded video PresentationState has changed to %d.", 164 | state); 165 | } 166 | 167 | private: 168 | FirebaseScene* scene; 169 | }; 170 | 171 | /// This function is called when the Future for the last call to the ad view's 172 | /// Initialize() method completes. 173 | static void onAdViewInitializeCompletionCallback( 174 | const firebase::Future& future, void* userData) { 175 | FirebaseScene* scene = static_cast(userData); 176 | if (future.error() == firebase::admob::kAdMobErrorNone) { 177 | scene->logMessage("Initializing the ad view completed successfully."); 178 | } else { 179 | scene->logMessage("Initializing the ad view failed."); 180 | scene->logMessage( 181 | "ERROR: Action failed with error code %d and message \"%s\".", 182 | future.error(), future.error_message()); 183 | } 184 | } 185 | 186 | /// This function is called when the Future for the last call to the ad view's 187 | /// LoadAd() method completes. 188 | static void onAdViewLoadAdCompletionCallback( 189 | const firebase::Future& future, void* userData) { 190 | FirebaseScene* scene = static_cast(userData); 191 | if (future.error() == firebase::admob::kAdMobErrorNone) { 192 | scene->logMessage("Loading the ad view completed successfully."); 193 | } else { 194 | scene->logMessage("Loading the ad view failed."); 195 | scene->logMessage( 196 | "ERROR: Action failed with error code %d and message \"%s\".", 197 | future.error(), future.error_message()); 198 | } 199 | } 200 | 201 | /// This function is called when the Future for the last call to the 202 | /// InterstitialAds's Initialize() method completes. 203 | static void onInterstitialAdInitializeCompletionCallback( 204 | const firebase::Future& future, void* userData) { 205 | FirebaseScene* scene = static_cast(userData); 206 | if (future.error() == firebase::admob::kAdMobErrorNone) { 207 | scene->logMessage( 208 | "Initializing the interstitial ad completed successfully."); 209 | } else { 210 | scene->logMessage("Initializing the interstitial ad failed."); 211 | scene->logMessage( 212 | "ERROR: Action failed with error code %d and message \"%s\".", 213 | future.error(), future.error_message()); 214 | } 215 | } 216 | 217 | /// This function is called when the Future for the last call to the 218 | /// InterstitialAds's LoadAd() method completes. 219 | static void onInterstitialAdLoadAdCompletionCallback( 220 | const firebase::Future& future, void* userData) { 221 | FirebaseScene* scene = static_cast(userData); 222 | if (future.error() == firebase::admob::kAdMobErrorNone) { 223 | scene->logMessage("Loading the interstitial ad completed successfully."); 224 | } else { 225 | scene->logMessage("Loading the interstitial ad failed."); 226 | scene->logMessage( 227 | "ERROR: Action failed with error code %d and message \"%s\".", 228 | future.error(), future.error_message()); 229 | } 230 | } 231 | 232 | /// This function is called when the Future for the last call to 233 | /// rewarded_video::Initialize() method completes. 234 | static void onRewardedVideoInitializeCompletionCallback( 235 | const firebase::Future& future, void* userData) { 236 | FirebaseScene* scene = static_cast(userData); 237 | if (future.error() == firebase::admob::kAdMobErrorNone) { 238 | scene->logMessage("Initializing rewarded video completed successfully."); 239 | } else { 240 | scene->logMessage("Initializing rewarded video failed."); 241 | scene->logMessage( 242 | "ERROR: Action failed with error code %d and message \"%s\".", 243 | future.error(), future.error_message()); 244 | } 245 | } 246 | 247 | /// This function is called when the Future for the last call to 248 | /// rewarded_video::LoadAd() method completes. 249 | static void onRewardedVideoLoadAdCompletionCallback( 250 | const firebase::Future& future, void* userData) { 251 | FirebaseScene* scene = static_cast(userData); 252 | if (future.error() == firebase::admob::kAdMobErrorNone) { 253 | scene->logMessage("Loading rewarded video completed successfully."); 254 | } else { 255 | scene->logMessage("Loading rewarded video failed."); 256 | scene->logMessage( 257 | "ERROR: Action failed with error code %d and message \"%s\".", 258 | future.error(), future.error_message()); 259 | // Rewarded Video returned an error. This might be because the developer did 260 | // not put their Rewarded Video ad unit into kRewardedVideoAdUnit above. 261 | scene->logMessage("WARNING: Is your Rewarded Video ad unit ID correct?"); 262 | scene->logMessage( 263 | "Ensure kRewardedVideoAdUnit is set to your own Rewarded Video ad unit " 264 | "ID."); 265 | } 266 | } 267 | 268 | /// Creates the Firebase scene. 269 | Scene* CreateFirebaseScene() { 270 | return FirebaseAdMobScene::createScene(); 271 | } 272 | 273 | /// Creates the FirebaseAdMobScene. 274 | Scene* FirebaseAdMobScene::createScene() { 275 | // Create the scene. 276 | auto scene = Scene::create(); 277 | 278 | // Create the layer. 279 | auto layer = FirebaseAdMobScene::create(); 280 | 281 | // Add the layer to the scene. 282 | scene->addChild(layer); 283 | 284 | return scene; 285 | } 286 | 287 | /// Initializes the FirebaseScene. 288 | bool FirebaseAdMobScene::init() { 289 | if (!Layer::init()) { 290 | return false; 291 | } 292 | 293 | auto visibleSize = Director::getInstance()->getVisibleSize(); 294 | cocos2d::Vec2 origin = Director::getInstance()->getVisibleOrigin(); 295 | 296 | // Intitialize Firebase AdMob. 297 | CCLOG("Initializing the AdMob with Firebase API."); 298 | firebase::admob::Initialize(*firebase::App::GetInstance(), kAdMobAppID); 299 | 300 | // Create the AdMob ad listener classes. 301 | adViewListener = new LoggingAdViewListener(this); 302 | interstitialAdListener = new LoggingInterstitialAdListener(this); 303 | rewardedVideoListener = new LoggingRewardedVideoListener(this); 304 | 305 | // Create the Firebase label. 306 | auto firebaseLabel = 307 | Label::createWithTTF("Firebase AdMob", "fonts/Marker Felt.ttf", 20); 308 | nextYPosition = 309 | origin.y + visibleSize.height - firebaseLabel->getContentSize().height; 310 | firebaseLabel->setPosition( 311 | cocos2d::Vec2(origin.x + visibleSize.width / 2, nextYPosition)); 312 | this->addChild(firebaseLabel, 1); 313 | 314 | const float scrollViewYPosition = nextYPosition - 315 | firebaseLabel->getContentSize().height - 316 | kUIElementPadding * 2; 317 | // Create the ScrollView on the Cocos2d thread. 318 | cocos2d::Director::getInstance() 319 | ->getScheduler() 320 | ->performFunctionInCocosThread( 321 | [=]() { this->createScrollView(scrollViewYPosition); }); 322 | 323 | // Create the AdMob ad view object. 324 | adView = new firebase::admob::BannerView(); 325 | // Create an ad size for the ad view. 326 | firebase::admob::AdSize adSize; 327 | adSize.ad_size_type = firebase::admob::kAdSizeStandard; 328 | adSize.width = kAdViewWidth; 329 | adSize.height = kAdViewHeight; 330 | logMessage("Initializing the ad view."); 331 | adView->Initialize(getWindowContext(), kAdViewAdUnit, adSize); 332 | adView->InitializeLastResult().OnCompletion( 333 | onAdViewInitializeCompletionCallback, this); 334 | 335 | // Set up the load ad view button. 336 | loadAdViewBtn = createButton(true, kLoadAdViewText); 337 | loadAdViewBtn->addTouchEventListener( 338 | [&](Ref* sender, cocos2d::ui::Widget::TouchEventType type) { 339 | cocos2d::ui::Button* button = static_cast(sender); 340 | switch (type) { 341 | case cocos2d::ui::Widget::TouchEventType::ENDED: 342 | // This simple example only allows loading the ad view once. Once 343 | // the load ad view button is pressed, we disable it for the 344 | // remainder of time that the application is running. For your app, 345 | // you can initialize and load as many ad views as you would like. 346 | // Just remember that only one ad view can be shown on the screen at 347 | // a time. 348 | button->setEnabled(false); 349 | logMessage("Setting the ad view listener."); 350 | adView->SetListener(adViewListener); 351 | logMessage("Loading the ad view."); 352 | adView->LoadAd(createAdRequest()); 353 | adView->LoadAdLastResult().OnCompletion( 354 | onAdViewLoadAdCompletionCallback, this); 355 | break; 356 | default: 357 | break; 358 | } 359 | }); 360 | this->addChild(loadAdViewBtn); 361 | 362 | // Set up the show/hide ad view button. 363 | showHideAdViewBtn = createButton(false, kShowAdViewText); 364 | showHideAdViewBtn->addTouchEventListener( 365 | [&](Ref* sender, cocos2d::ui::Widget::TouchEventType type) { 366 | cocos2d::ui::Button* button = static_cast(sender); 367 | std::string titleText = button->getTitleText(); 368 | switch (type) { 369 | case cocos2d::ui::Widget::TouchEventType::ENDED: 370 | if (titleText.compare(kShowAdViewText) == 0) { 371 | logMessage("Showing the ad view."); 372 | adView->Show(); 373 | button->setTitleText(kHideAdViewText); 374 | } else { 375 | logMessage("Hiding the ad view."); 376 | adView->Hide(); 377 | button->setTitleText(kShowAdViewText); 378 | } 379 | break; 380 | default: 381 | break; 382 | } 383 | }); 384 | this->addChild(showHideAdViewBtn); 385 | 386 | // Set up the move ad view button. 387 | moveAdViewBtn = createButton(false, kMoveAdViewText); 388 | moveAdViewBtn->addTouchEventListener( 389 | [&](Ref* sender, cocos2d::ui::Widget::TouchEventType type) { 390 | firebase::admob::BannerView::Position adViewPosition = 391 | static_cast( 392 | adViewPositions[adViewPositionIndex]); 393 | switch (type) { 394 | case cocos2d::ui::Widget::TouchEventType::ENDED: 395 | logMessage("Moving the ad view to %s.", 396 | adViewPositionStrings[adViewPositionIndex].c_str()); 397 | adView->MoveTo(adViewPosition); 398 | ++adViewPositionIndex; 399 | adViewPositionIndex = (adViewPositionIndex == adViewPositionsCount) 400 | ? 0 401 | : adViewPositionIndex; 402 | break; 403 | default: 404 | break; 405 | } 406 | }); 407 | this->addChild(moveAdViewBtn); 408 | 409 | // Create the AdMob IntersitialAd object. 410 | interstitialAd = new firebase::admob::InterstitialAd(); 411 | logMessage("Initializing the interstitial ad."); 412 | interstitialAd->Initialize(getWindowContext(), kInterstitialAdUnit); 413 | interstitialAd->InitializeLastResult().OnCompletion( 414 | onInterstitialAdInitializeCompletionCallback, this); 415 | 416 | // Set up the load interstitial ad button. 417 | loadInterstitialAdBtn = createButton(true, kLoadInterstitialText); 418 | loadInterstitialAdBtn->addTouchEventListener( 419 | [&](Ref* sender, cocos2d::ui::Widget::TouchEventType type) { 420 | cocos2d::ui::Button* button = static_cast(sender); 421 | switch (type) { 422 | case cocos2d::ui::Widget::TouchEventType::ENDED: 423 | // Once the load interstitial button has been pressed, we disable it 424 | // until the interstitial ad has been displayed to and dismissed 425 | // by the user. The load interstitial button is reenabled in the 426 | // update() method. 427 | button->setEnabled(false); 428 | logMessage("Setting the InterstitialAd listener."); 429 | interstitialAd->SetListener(interstitialAdListener); 430 | logMessage("Loading the interstitial ad."); 431 | interstitialAd->LoadAd(createAdRequest()); 432 | interstitialAd->LoadAdLastResult().OnCompletion( 433 | onInterstitialAdLoadAdCompletionCallback, this); 434 | break; 435 | default: 436 | break; 437 | } 438 | }); 439 | this->addChild(loadInterstitialAdBtn); 440 | 441 | // Set up the show interstitial ad button. 442 | showInterstitialAdBtn = createButton(false, kShowInterstitialText); 443 | showInterstitialAdBtn->addTouchEventListener( 444 | [&](Ref* sender, cocos2d::ui::Widget::TouchEventType type) { 445 | cocos2d::ui::Button* button = static_cast(sender); 446 | switch (type) { 447 | case cocos2d::ui::Widget::TouchEventType::ENDED: 448 | // The show intersitial button is enabled in the update() method 449 | // when the interstial ad has successfully loaded. Here the show 450 | // interstitial button has been pressed by the user, so we disable 451 | // the button and display the interstitial ad to the user. 452 | button->setEnabled(false); 453 | logMessage("Showing the interstitial ad."); 454 | interstitialAd->Show(); 455 | // Invalidate all Futures and enable loadInterstitialAdBtn. 456 | interstitialAdShown = true; 457 | break; 458 | default: 459 | break; 460 | } 461 | }); 462 | this->addChild(showInterstitialAdBtn); 463 | 464 | logMessage("Initializing rewarded video."); 465 | rewarded_video::Initialize(); 466 | rewarded_video::InitializeLastResult().OnCompletion( 467 | onRewardedVideoInitializeCompletionCallback, this); 468 | 469 | // Set up the load rewarded video button. 470 | loadRewardedVideoBtn = createButton(true, kLoadRewardedVideoText); 471 | loadRewardedVideoBtn->addTouchEventListener( 472 | [&](Ref* sender, cocos2d::ui::Widget::TouchEventType type) { 473 | cocos2d::ui::Button* button = static_cast(sender); 474 | switch (type) { 475 | case cocos2d::ui::Widget::TouchEventType::ENDED: 476 | // Once the load rewarded video button has been pressed, we disable 477 | // it until the rewarded video has been displayed to and dismissed 478 | // by the user. The load rewarded video button is reenabled in the 479 | // update() method. 480 | button->setEnabled(false); 481 | logMessage("Setting the rewarded video listener."); 482 | rewarded_video::SetListener(rewardedVideoListener); 483 | logMessage("Loading the rewarded video."); 484 | rewarded_video::LoadAd(kRewardedVideoAdUnit, createAdRequest()); 485 | rewarded_video::LoadAdLastResult().OnCompletion( 486 | onRewardedVideoLoadAdCompletionCallback, this); 487 | break; 488 | default: 489 | break; 490 | } 491 | }); 492 | this->addChild(loadRewardedVideoBtn); 493 | 494 | // Set up the show rewarded video button. 495 | showRewardedVideoBtn = createButton(false, kShowRewardedVideoText); 496 | showRewardedVideoBtn->addTouchEventListener( 497 | [&](Ref* sender, cocos2d::ui::Widget::TouchEventType type) { 498 | cocos2d::ui::Button* button = static_cast(sender); 499 | switch (type) { 500 | case cocos2d::ui::Widget::TouchEventType::ENDED: 501 | // The show rewarded video button is enabled in the update() method 502 | // when the rewarded video has successfully loaded. Here the show 503 | // rewarded video button has been pressed by the user, so we disable 504 | // the button and display the rewarded video to the user. 505 | button->setEnabled(false); 506 | logMessage("Showing the rewarded video ad."); 507 | rewarded_video::Show(getWindowContext()); 508 | // Invalidate all Futures and enable loadRewardedVideoBtn. 509 | rewardedVideoAdShown = true; 510 | break; 511 | default: 512 | break; 513 | } 514 | }); 515 | this->addChild(showRewardedVideoBtn); 516 | 517 | // Create the close app menu item. 518 | auto closeAppItem = MenuItemImage::create( 519 | "CloseNormal.png", "CloseSelected.png", 520 | CC_CALLBACK_1(FirebaseScene::menuCloseAppCallback, this)); 521 | closeAppItem->setContentSize(cocos2d::Size(25, 25)); 522 | // Position the close app menu item on the top-right corner of the screen. 523 | closeAppItem->setPosition(cocos2d::Vec2( 524 | origin.x + visibleSize.width - closeAppItem->getContentSize().width / 2, 525 | origin.y + visibleSize.height - 526 | closeAppItem->getContentSize().height / 2)); 527 | 528 | // Create the Menu for touch handling. 529 | auto menu = Menu::create(closeAppItem, NULL); 530 | menu->setPosition(cocos2d::Vec2::ZERO); 531 | this->addChild(menu, 1); 532 | 533 | // Schedule the update method for this scene. 534 | this->scheduleUpdate(); 535 | 536 | return true; 537 | } 538 | 539 | // Called automatically every frame. The update is scheduled in `init()`. 540 | void FirebaseAdMobScene::update(float delta) { 541 | // If the ad view's Initialize() future has completed successfully, enable the 542 | // ad view buttons. 543 | if (adView->InitializeLastResult().status() == 544 | firebase::kFutureStatusComplete && 545 | adView->InitializeLastResult().error() == 546 | firebase::admob::kAdMobErrorNone) { 547 | // If ad view's LoadAd() has not been called yet, enable the load ad view 548 | // button. 549 | if (adView->LoadAdLastResult().status() == firebase::kFutureStatusInvalid) { 550 | loadAdViewBtn->setEnabled(true); 551 | } 552 | showHideAdViewBtn->setEnabled(true); 553 | moveAdViewBtn->setEnabled(true); 554 | } 555 | 556 | // Once the InterstitialAd::Intitialize() future has completed successfully, 557 | // enable the interstitial ad buttons. 558 | if (interstitialAd->InitializeLastResult().status() == 559 | firebase::kFutureStatusComplete && 560 | interstitialAd->InitializeLastResult().error() == 561 | firebase::admob::kAdMobErrorNone) { 562 | // If InterstitialAd::LoadAd() method has not been called yet, enable the 563 | // load interstitial ad button. 564 | if (interstitialAd->LoadAdLastResult().status() == 565 | firebase::kFutureStatusInvalid) { 566 | loadInterstitialAdBtn->setEnabled(true); 567 | } 568 | // Once the InterstitialAd::LoadAd() future has completed successfully, 569 | // enable the show interstitial ad button. 570 | if (interstitialAd->LoadAdLastResult().status() == 571 | firebase::kFutureStatusComplete && 572 | interstitialAd->LoadAdLastResult().error() == 573 | firebase::admob::kAdMobErrorNone && 574 | !interstitialAdShown) { 575 | showInterstitialAdBtn->setEnabled(true); 576 | } 577 | // Once the InterstitialAd::Show() future has completed and the interstitial 578 | // ad has been displayed and dismissed by the user, clean up the existing 579 | // interstitial ad object and create a new one. Note: InterstitialAd is a 580 | // single-use object that can load and show a single AdMob interstitial ad. 581 | if (interstitialAd->ShowLastResult().status() == 582 | firebase::kFutureStatusComplete && 583 | interstitialAd->presentation_state() == 584 | firebase::admob::InterstitialAd::kPresentationStateHidden) { 585 | // Invalidate all Futures and enable loadInterstitialAdBtn. 586 | interstitialAdShown = false; 587 | delete interstitialAd; 588 | interstitialAd = new firebase::admob::InterstitialAd(); 589 | logMessage("Initializing the interstitial ad."); 590 | interstitialAd->Initialize(getWindowContext(), kInterstitialAdUnit); 591 | interstitialAd->InitializeLastResult().OnCompletion( 592 | onInterstitialAdInitializeCompletionCallback, this); 593 | } 594 | // If the InterstitialAd::LoadAd() future completed but there was an error, 595 | // then clean up the existing interstitial ad object and create a new one. 596 | if (interstitialAd->InitializeLastResult().status() == 597 | firebase::kFutureStatusComplete && 598 | interstitialAd->LoadAdLastResult().status() == 599 | firebase::kFutureStatusComplete && 600 | interstitialAd->LoadAdLastResult().error() != 601 | firebase::admob::kAdMobErrorNone) { 602 | // Invalidate all Futures and enable loadInterstitialAdBtn. 603 | interstitialAdShown = false; 604 | delete interstitialAd; 605 | interstitialAd = new firebase::admob::InterstitialAd(); 606 | logMessage("Reinitializing the interstitial ad."); 607 | interstitialAd->Initialize(getWindowContext(), kInterstitialAdUnit); 608 | interstitialAd->InitializeLastResult().OnCompletion( 609 | onInterstitialAdInitializeCompletionCallback, this); 610 | } 611 | } 612 | 613 | // Once the rewarded_video::Intitialize() future has completed successfully, 614 | // enable the rewarded video buttons. 615 | if (rewarded_video::InitializeLastResult().status() == 616 | firebase::kFutureStatusComplete && 617 | rewarded_video::InitializeLastResult().error() == 618 | firebase::admob::kAdMobErrorNone) { 619 | // If rewarded_video::LoadAd() method has not been called yet, enable the 620 | // load rewarded video button. 621 | if (rewarded_video::LoadAdLastResult().status() == 622 | firebase::kFutureStatusInvalid) { 623 | loadRewardedVideoBtn->setEnabled(true); 624 | } 625 | // Once the rewarded_video::LoadAd() future has completed successfully, 626 | // enable the show rewarded video button. 627 | if (rewarded_video::LoadAdLastResult().status() == 628 | firebase::kFutureStatusComplete && 629 | rewarded_video::LoadAdLastResult().error() == 630 | firebase::admob::kAdMobErrorNone && 631 | !rewardedVideoAdShown) { 632 | showRewardedVideoBtn->setEnabled(true); 633 | } 634 | // Once the rewarded_video::Show() future has completed and the rewarded 635 | // video has been displayed and dismissed by the user, invalidate all 636 | // existing futures for rewarded_video methods and enable the load rewarded 637 | // video button. 638 | if (rewarded_video::ShowLastResult().status() == 639 | firebase::kFutureStatusComplete && 640 | rewarded_video::presentation_state() == 641 | firebase::admob::rewarded_video::kPresentationStateHidden) { 642 | // Invalidate all Futures and enable loadRewardedVideoBtn. 643 | rewardedVideoAdShown = false; 644 | rewarded_video::Destroy(); 645 | logMessage("Initializing rewarded video."); 646 | rewarded_video::Initialize(); 647 | rewarded_video::InitializeLastResult().OnCompletion( 648 | onRewardedVideoInitializeCompletionCallback, this); 649 | } 650 | // If the rewarded_video::LoadAd() future completed but there was an error, 651 | // then clean up the existing rewarded_video namespace and reinitialize. 652 | if (rewarded_video::InitializeLastResult().status() == 653 | firebase::kFutureStatusComplete && 654 | rewarded_video::LoadAdLastResult().status() == 655 | firebase::kFutureStatusComplete && 656 | rewarded_video::LoadAdLastResult().error() != 657 | firebase::admob::kAdMobErrorNone) { 658 | // Invalidate all Futures and enable loadRewardedVideoBtn. 659 | rewardedVideoAdShown = false; 660 | rewarded_video::Destroy(); 661 | logMessage("Reinitializing rewarded video."); 662 | rewarded_video::Initialize(); 663 | rewarded_video::InitializeLastResult().OnCompletion( 664 | onRewardedVideoInitializeCompletionCallback, this); 665 | } 666 | } 667 | } 668 | 669 | firebase::admob::AdRequest FirebaseAdMobScene::createAdRequest() { 670 | firebase::admob::AdRequest request; 671 | // If the app is aware of the user's gender, it can be added to the targeting 672 | // information. Otherwise, "unknown" should be used. 673 | request.gender = firebase::admob::kGenderUnknown; 674 | 675 | // This value allows publishers to specify whether they would like the request 676 | // to be treated as child-directed for purposes of the Children’s Online 677 | // Privacy Protection Act (COPPA). 678 | // See http://business.ftc.gov/privacy-and-security/childrens-privacy. 679 | request.tagged_for_child_directed_treatment = 680 | firebase::admob::kChildDirectedTreatmentStateTagged; 681 | 682 | // The user's birthday, if known. Note that months are indexed from one. 683 | request.birthday_day = kBirthdayDay; 684 | request.birthday_month = kBirthdayMonth; 685 | request.birthday_year = kBirthdayYear; 686 | 687 | // Additional keywords to be used in targeting. 688 | request.keyword_count = sizeof(kKeywords) / sizeof(kKeywords[0]); 689 | request.keywords = kKeywords; 690 | 691 | // "Extra" key value pairs can be added to the request as well. Typically 692 | // these are used when testing new features. 693 | static const firebase::admob::KeyValuePair kRequestExtras[] = { 694 | {"the_name_of_an_extra", "the_value_for_that_extra"}}; 695 | request.extras_count = sizeof(kRequestExtras) / sizeof(kRequestExtras[0]); 696 | request.extras = kRequestExtras; 697 | 698 | // This example uses ad units that are specially configured to return test ads 699 | // for every request. When using your own ad unit IDs, however, it's important 700 | // to register the device IDs associated with any devices that will be used to 701 | // test the app. This ensures that regardless of the ad unit ID, those 702 | // devices will always receive test ads in compliance with AdMob policy. 703 | // 704 | // Device IDs can be obtained by checking the logcat or the Xcode log while 705 | // debugging. They appear as a long string of hex characters. 706 | request.test_device_id_count = 707 | sizeof(kTestDeviceIDs) / sizeof(kTestDeviceIDs[0]); 708 | request.test_device_ids = kTestDeviceIDs; 709 | 710 | return request; 711 | } 712 | 713 | /// Handles the user tapping on the close app menu item. 714 | void FirebaseAdMobScene::menuCloseAppCallback(Ref* pSender) { 715 | CCLOG("Cleaning up AdMob C++ resources."); 716 | delete adView; 717 | delete interstitialAd; 718 | rewarded_video::Destroy(); 719 | delete adViewListener; 720 | delete interstitialAdListener; 721 | delete rewardedVideoListener; 722 | firebase::admob::Terminate(); 723 | 724 | // Close the cocos2d-x game scene and quit the application. 725 | Director::getInstance()->end(); 726 | 727 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 728 | exit(0); 729 | #endif 730 | } 731 | --------------------------------------------------------------------------------