LoginSignup
2

More than 3 years have passed since last update.

Cocos2d-x v3.17にFirebase SDK C++ を入れて匿名認証を実装する(2019年度版cmake対応)

Posted at

概要

誰がなんといおうと、ぼくはまだcocos2d-xを使い続ける所存です。
(Unityも勉強してはいるんだけどね)
そんなわけで、FirebaseのC++ SDKを最新のものに入れた際の設定をまとめました。

ゴール

  • Firebase匿名認証を使ってiOS/Androidで認証する
  • Androidはcmakeでビルドする

前提環境

  • Mac OS X (10.14)
  • cocos2d-x (v3.17.1)
  • Xcode10.3
  • Android Studio 3.5
  • Gradle 5.4.1
  • Android NDK r13b

Firebaseのプロジェクト作成&ネイティブSDK導入

ここらへんは、公式に記載された通りにやっていきます。

アプリの追加

Project Overviewから「プロジェクトの設定」を選択します。
そして、設定画面からアプリの追加を行います。

image.png

image.png

あとは、以下のような画面になるんで手順どおりに進めていってアプリを作成します。

image.png

匿名認証の設定

Firebaseにて、匿名認証の設定を行います。
image.png

環境構築

みんな大好きC++の環境構築やっていきましょうね(にっこり)

iOS版

最初は書いてある通りに行う

C++ プロジェクトに Firebase を追加する
https://firebase.google.com/docs/cpp/setup?hl=ja

上記の「ステップ 5」の1「Firebase C++ SDK をダウンロードし、適切な場所で解凍します。」まではそのまま行います。
また、 Firestore C++ SDK のディレクトリは firebase_cpp_sdk みたいな名前にし、 proj.ios-macproj.android と同じ階層の場所に配置します。(という前提でここから進めますが、別の場所に配置する場合はパスの指定は適宜置き換えて下さい)

Podfileの作成

このあたりから日本語版ではちょっと嘘が書かれはじめます(更新されてないだけですが)。
2019/9/2現在、Firebase SDK は 6.3.0 まで上がってますので、記載のやり方だと古いものが入っちゃいます。
また、そのバージョンだと iOS8 以上が必須になります。

$ cp your-app-directory
$ pod init
Podfile
# Uncomment the next line to define a global platform for your project
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

target 'MyTest-desktop' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

  # Pods for MyTest-desktop

end

target 'MyTest-mobile' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

  # Pods for MyTest-mobile
  pod 'Firebase' # これは入れといた方がよさげ
  pod 'Firebase/Analytics' # これも入れといた方がよさげ
  pod 'Firebase/Core' # これもたぶん必須。その他は使いたいものを入れる
  pod 'Firebase/Auth' 

end

その後、インストールします。

$ pod update

すると、cocos2d-xの場合 https://firebase.google.com/docs/admob/cpp/cocos2d-x?hl=ja に記載されてるようなエラーがでます。

CocoaPods が、いくつかのプロパティで $(inherited) が欠落しているという警告を発します。Xcode で MyGame-mobile ターゲットのビルド設定に移動し、次の各ビルド設定のリストの最後に $(inherited) を追加します。

  • Other Linker Flags
  • Preprocessor Macros
  • Library Search Paths

というわけで、それらの設定をします。ただ、なぜかMyGame-desktop側でも警告でちゃうんでそっちも合わせて同じ設定をします。

(例:Processor Macros)
image.png

BuildSetting

Framework Search Pathsへの追加

[Framework Search Paths]に $(PROJECT_DIR)/../firebase_cpp_sdk/frameworks/ios/universal を追加します。

image.png

その上にある、 "${PODS_ROOT}/FirebaseAnalytics/Frameworks""${PODS_ROOT}/GoogleAppMeasurement/Frameworks" もいつのまにか入ってきてました。
必要っぽいのでとりあえず残しておきます。

Header Search Pathsへの追加

[Header Search Paths] に $(PROJECT_DIR)/../firebase_cpp_sdk/include を追加します。

image.png

必要なライブラリを追加

firebase_cpp_sdk/frameworks/ios/universal の中にあるそれぞれ必要なライブラリをプロジェクトに追加します。
ライブラリは、使うものによって異なります。

詳細は https://firebase.google.com/docs/cpp/setup (英語版) に記載されています。
image.png

image.png

Linked Frameworks and Librariesにフレームワークを追加

Linked Frameworks and Libraries に以下を入れます。

  • MediaPlayer.framework
  • GameController.framework

image.png

このあたりは、使うフレームワークによっても変わってきそう。

Android版

現在、Android NDKのbuildはcmakeが推奨されており、Firebase C++ SDKも公式ドキュメントではcmakeの利用が推奨されてます。ということで、それで設定します。

公式(C++)
https://firebase.google.com/docs/cpp/setup?platform=android#nav-buttons-1

google-services.jsonの配置

まずはFirebaseプロジェクトを作成し、google-services.jsonを以下の場所に配置します。

image.png

project/build.gradleの設定

続いて、プロジェクト側(proj.android直下)のbuild.gradleに以下を追加します。

project/build.gradle

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.0'
        classpath 'com.google.gms:google-services:4.3.1' // ここを追加
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

gradle.propetiesの設定

次はgradle.propertiesです。ついでにここで64bit対応もしちゃいます。

// 省略
PROP_APP_ABI=armeabi-v7a:arm64-v8a // 変更
// 以下を追加
PROP_BUILD_TYPE=cmake
systemProp.firebase_cpp_sdk.dir=【フルパス】/firebase_cpp_sdk

systemProp.firebase_cpp_sdk.dir には、最初に配置した firebase_cpp_sdk へのフルパスを指定します。

settings.gradleの設定

続いて、以下を追加します。これによりFirebaseのC++側がビルドされます(と思うよ)

settings.gradle
def firebase_cpp_sdk_dir = System.getProperty('firebase_cpp_sdk.dir')
gradle.ext.firebase_cpp_sdk_dir = "$firebase_cpp_sdk_dir"
includeBuild "$firebase_cpp_sdk_dir"

app/build.gradleの設定

次に、アプリの方のbuild.gradle(app直下)にも以下を追加します。
こちらはいくつか追加する箇所があります。

app/build.gradle

android {
    // 省略
    defaultConfig {
        // 省略
        externalNativeBuild {
            if (PROP_BUILD_TYPE == 'ndk-build') {
                // 省略
            }
            else if (PROP_BUILD_TYPE == 'cmake') {
                cmake {
                    targets 'MyGame'
                    // "-DFIREBASE_CPP_SDK_DIR=$gradle.firebase_cpp_sdk_dir" を追加
                    arguments "-DCMAKE_FIND_ROOT_PATH=", "-DANDROID_STL=c++_static", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_NEON=TRUE", "-DFIREBASE_CPP_SDK_DIR=$gradle.firebase_cpp_sdk_dir"
                    cppFlags "-frtti -fexceptions -fsigned-char"
                }
            }
        }

        ndk {
            abiFilters = []
            abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})
        }
    }
    // 省略
}

// 省略

dependencies {
    // 入れたいSDKを追加する
    implementation 'com.google.firebase:firebase-analytics:17.2.0'
    implementation 'com.google.firebase:firebase-auth:19.0.0'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':libcocos2dx')
}
// 以下を追加
apply plugin: 'com.google.gms.google-services'  // Google Play services Gradle plugin
apply from: "$gradle.firebase_cpp_sdk_dir/Android/firebase_dependencies.gradle"

// 入れたいC++のライブラリを指定する
firebaseCpp.dependencies {
    analytics
    auth
}

CMakeLists.txt の修正

最後に、CMakeLists.txtを修正します。

# 中間あたり
target_include_directories(${APP_NAME}
        PRIVATE Classes
        PRIVATE ${COCOS2DX_ROOT_PATH}/cocos/audio/include/
        PRIVATE firebase_cpp_sdk/include/ # 追加(ヘッダーをインクルード)
)
# 省略
# 最後に追加
if(ANDROID)
    # Add Firebase libraries to the target using the function from the SDK.
    add_subdirectory(${FIREBASE_CPP_SDK_DIR} bin/ EXCLUDE_FROM_ALL)

    # The Firebase C++ library `firebase_app` is required,
    # and it must always be listed last.

    # Add the Firebase SDKs for the products you want to use in your app
    # For example, to use Analytics, Firebase Authentication, and Firebase Realtime Database
    set(firebase_libs firebase_analytics firebase_auth firebase_app)
    target_link_libraries(${APP_NAME} "${firebase_libs}")
endif()

上記では、 set(firebase_libs firebase_analytics firebase_auth firebase_app) を指定しています。注意書きにあるように、 firebase_app は必須で、かつ最後に指定しないといけないそうです。

コーディング

今回は匿名認証なので、以下の通り実装します。

iOS側

どこにも必要とは書いてないんですが、これ入れないとnullが返ってくる…。

AppDelegate.mm

#import "AppController.h"
#import "cocos2d.h"
#import "AppDelegate.h"
#import "RootViewController.h"
#import <Firebase/Firebase.h> // 追加

// (省略)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [FIRApp configure]; // 追加

    // 以下省略
}

上記をいれないと、ログで The default Firebase app has not yet been configured. Add [FIRApp configure]; (FirebaseApp.configure() in Swift) to your application initialization. Read more: https://goo.gl/ctyzm8. と怒られるので必要なのでしょう。

Android側

Android側は特に何もJavaに追加はしてません。

C++側

AppDelegateに以下のように記載します。

AppDelegate.cpp
#include "AppDelegate.h"
#include "HelloWorldScene.h"
#include "firebase/app.h"
#include "firebase/auth.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "platform/android/jni/JniHelper.h"
#endif

// (省略)
bool AppDelegate::applicationDidFinishLaunching() {

   // (省略)
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
    auto app = firebase::App::Create(firebase::AppOptions(), JniHelper::getEnv(), JniHelper::getActivity());
#else
    auto app = firebase::App::Create(firebase::AppOptions());
#endif
    auto auth = firebase::auth::Auth::GetAuth(app);
    auto result = auth->SignInAnonymously();
    result.OnCompletion([](const firebase::Future<firebase::auth::User*>& user) {
        auto u = user.result();
    }); 
}

最後実行すると

こんな感じで、Firebaseに匿名ユーザーが登録されます。
image.png

トラブルシューティング

ぼくが設定してる時に出くわしたエラーとその対処法です。

環境構築編

iOS

"OBJC_CLASS$XXXXX", referenced from: とでる場合

iOSでの設定中に以下のエラーが出ました。

Undefined symbols for architecture x86_64:### 
  "_OBJC_CLASS_$_MPMoviePlayerController", referenced from:
      objc-class-ref in libcocos2d iOS.a(UIVideoPlayer-ios.o)
  "_MPMoviePlayerPlaybackDidFinishNotification", referenced from:
      -[UIVideoViewWrapperIos dealloc] in libcocos2d iOS.a(UIVideoPlayer-ios.o)
      -[UIVideoViewWrapperIos setURL::] in libcocos2d iOS.a(UIVideoPlayer-ios.o)
  "_MPMoviePlayerPlaybackStateDidChangeNotification", referenced from:
      -[UIVideoViewWrapperIos dealloc] in libcocos2d iOS.a(UIVideoPlayer-ios.o)
      -[UIVideoViewWrapperIos setURL::] in libcocos2d iOS.a(UIVideoPlayer-ios.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

この場合、ライブラリが足りていないというエラーらしく、Linked Frameworks and Librariesに MediaPlayer.frameworkを入れることで解決しました。

image.png

足りてないライブラリの一覧はこちらに詳しく乗ってます。

Xcodeでライブラリリンク時に発生するエラーに対応するframework
https://joyplot.com/documents/2016/09/18/xcode-link-error-framework/

コーディング編

firebase::AppがNULLが返却される

ターミナル上には以下の警告がでてる場合

[Firebase/Core][I-COR000003] The default Firebase app has not yet been configured. Add `[FIRApp configure];` (`FirebaseApp.configure()` in Swift) to your application initialization. Read more: https://goo.gl/ctyzm8.
[Firebase/Analytics][I-ACS023007] Analytics v.60101000 started
[Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see http://goo.gl/RfcP7r)
[Firebase/InstanceID][I-IID001000] Firebase not set up correctly, nil or empty senderID.
ERROR: Unable to configure Firebase app (Could not configure Firebase InstanceID. GCM_SENDER_ID must not be nil or empty.)

iOS側のコーディングが足りてない場合に発生します。 AppDelegate.mm にも処理を追加する必要があります。

参考

Add Firebase to your C++ project
https://firebase.google.com/docs/cpp/setup

Cocos2d-x 3.17.1からビルドがcmakeに変更された件に対応する、ほかトラブル対応
https://takachan.hatenablog.com/entry/2019/02/03/014844

Xcodeでライブラリリンク時に発生するエラーに対応するframework
https://joyplot.com/documents/2016/09/18/xcode-link-error-framework/

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2