自己紹介
- 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使ってるの?」