Edited at

react nativeでfirebaseのネイティブSDKを操作する

More than 1 year has passed since last update.


自己紹介


  • uryyyyyyy: しばたこ

  • 本業はアドテクでScala/React/TypeScript

  • 副業でReact Native

最近そこそこバズった記事→ReduxでのMiddleware不要論



話すこと


  • React NativeでNative APIを扱ってみる

  • Swift/Kotlinでやってみる

お題として今回はFirebase SDKとGoogle認証を扱ってみます。

Firebaseのイベントトラッキングの方ではNative Moduleを扱う話、

認証周りでは、もう少し拡張してView/ViewControllerを扱ってみる話をします。

完成形



ところで

FirebaseにはNativeのSDKとWebのSDKがあるのは大丈夫ですよね?

ちゃんと調べてないですが、違いはAnalyticsが弱いとかPush通知とかだと思います。

せっかくのReact Nativeなので、今回はNativeのSDKの話をします。



ところで2

アプリで認証するときに、いちいちWebViewでグーグルにログインさせるのはダサいですね?

iOS/Androidともに、OS側で既にログインされていればそのまま連携できる仕組みがあります。

せっかくのReact Nativeなので、今回はNativeでの話をします。



準備



iOS/Androidのライブラリ周りの準備


iOS


  • Podsの設定をする。

  • Podfileで依存ライブラリを書く


Android


  • デフォルトではパッケージ名が com.<app name> とかなので、直す


    • AndroidManifestのpackage

    • build.gradleのapplicationIdを直す



  • build.gradleで依存ライブラリを書く



コードをSwift/Kotlinへ変更する


  • iOS


    • AppDelegateをswiftに書き直す

    • XX-Bridging-Header.hを用意する




swift/AppDelegate.swift

import UIKit

@objc(AppDelegate)
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow.init(frame: UIScreen.main.bounds)

//----RCTRootView----
let settings = RCTBundleURLProvider.sharedSettings()
let jsCodeLocation: URL = settings!.jsBundleURL(forBundleRoot: "index.ios", fallbackResource: nil)
let rootView = RCTRootView.init(bundleURL: jsCodeLocation as URL!, moduleName: "ReactNativeSample_ios", initialProperties: nil, launchOptions: launchOptions)
rootView?.backgroundColor = UIColor.init(red: 1.0, green: 1.0, blue: 1.0, alpha: 1)
//----RCTRootView----

let rootViewController = UIViewController()
rootViewController.view = rootView;
self.window?.rootViewController = rootViewController;
self.window?.makeKeyAndVisible()
return true
}

///色々
}



ReactNativeSample_ios-Bridging-Header.h

#import <React/RCTBundleURLProvider.h>

#import <React/RCTRootView.h>
#import <React/RCTBridgeModule.h>
#import "AppDelegate.h"


  • Android


    • 拡張子ktのファイルを書くと、AndroidStudioがbuild.gradleとか直してくれる。


    • src/main/java -> kotlinに直したり

    • MainActivity、MainApplicationをkotlin化する




MainActivity.kt

package com.github.uryyyyyyy.reactnative.android

import com.facebook.react.ReactActivity

class MainActivity : ReactActivity() {

/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
override fun getMainComponentName(): String? {
return "ReactNativeSample_android"
}
}



MainApplication.kt

package com.github.uryyyyyyy.reactnative.android

import android.app.Application

import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.shell.MainReactPackage
import com.facebook.soloader.SoLoader
import com.github.uryyyyyyy.reactnative.android.myModules.MyPackage

import java.util.Arrays

class MainApplication : Application(), ReactApplication {

private val mReactNativeHost = object : ReactNativeHost(this) {
override fun getUseDeveloperSupport(): Boolean {
return BuildConfig.DEBUG
}

override fun getPackages(): List<ReactPackage> {
return Arrays.asList<ReactPackage>(
MainReactPackage(),
MyPackage()
)
}
}

override fun getReactNativeHost(): ReactNativeHost {
return mReactNativeHost
}

override fun onCreate() {
super.onCreate()
SoLoader.init(this, /* native exopackage */ false)
}
}




Firebaseの導入



Firebaseコンソール


  • プロジェクト作り

  • Appを追加し、

  • 設定ファイルをダウンロードしてアプリに追加し、

  • SDKを入れたりする。



イベント飛ばしてみる


iOS


  • objective-Cでヘッダを書く

  • swiftでFirebaseの処理を書く

  • JSでそれを呼び出す。


MyModule.swift

  @objc(callFunc:)

func callFunc(num: NSInteger) {
print("num");
print(num);
FIRAnalytics.setUserPropertyString("favorite", forName: "curry")

FIRAnalytics.logEvent(withName: kFIREventSelectContent, parameters: [
kFIRParameterContentType:"count" as NSObject,
kFIRParameterItemID:"1" as NSObject
])
}



Android


  • ReactContextBaseJavaModuleを継承したクラスで処理を書く

  • ReactPackageを継承したクラスを作り、上記クラスを追加する

  • MainApplicationで上記クラスを追加する。

  • JSでそれを呼び出す。


MyModule.kt

    @ReactMethod

fun sendEvent() {
val mFirebaseAnalytics = FirebaseAnalytics.getInstance(reactApplicationContext)
val bundle = Bundle()
bundle.putString(FirebaseAnalytics.Param.ITEM_ID, "id")
bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, "name")
bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "image")
Log.i("myActivitysssss", mFirebaseAnalytics.toString())
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle)
}



Google認証してみる。

力尽きた。。。

デモだけお見せします。後で書きます。。。きっと。。。



まとめ


  • 普通にブリッジできるよ。

  • SDKを触るだけなら言語詳しくなくてもなんとかなるよ。

  • 「え、React Nativeなのにまだ Firebase Web SDK使ってるの?」