uniapp封装原生 firebase-analytics 插件

634 阅读4分钟

uniapp封装原生 firebase-analytics 插件

因为有这个需求,先查看官方文档,官方提供了上传配置文件功能,但是并没有开放对应的api,然后又找了插件市场里面,并没有合适的,所以就自己简单弄了一下,后续有其他需要原生的功能也可以使用类似的方式实现。

这里只是一个简单的记录流程,方便后续做参考。

1. 在 firebase 的后台创建项目

如果有这个需求,默认大家这个步骤都会,按照后台指示一步一步创建即可,因为 uniapp 如果要集成goole分析,需要Android和ios的配置文件,所以Android和ios都要创建。

2. 将配置文件集成到 uniapp 中

  1. 找到项目的 manifest.json,点击 App模块配置
  2. 找到 Statistic 配置模块,勾选 Goole Analytics for Firebase
  3. 上传刚才对应的 Android 和 iOS 配置文件

前置条件已经完成,现在开始编写原生的插件。

简单实现插件功能

参考官网

首先按照官网将环境搭建好,本文不详细描写环境的搭建。

环境搭建好后在官网文档上下载好离线的 UniPlugin-Hello-AS 工程,并在android studio中打开

开始新建我们自己的 plugin

项目根目录右键 -> New -> Module -> Android Library -> 填写部分信息 -> Finish

image01.png

当然,你也可以复制一个uniapp官方封装好的插件自己更改文件也行,这样配置文件简单改一下就行了......

更改我们自己插件 build.gradle 文件

引入 uniapp 官方的依赖和firebase-analytics的依赖

找到 dependencies 项,更改为下面所示(我也是复制过来新加了一些......)

dependencies {
    implementation 'com.google.android.gms:play-services-measurement-api:22.1.0'
    compileOnly fileTree(dir: 'libs', include: ['*.jar'])

    compileOnly fileTree(dir: '../app/libs', include: ['uniapp-v8-release.aar'])

    compileOnly 'androidx.recyclerview:recyclerview:1.0.0'
    compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
    compileOnly 'androidx.appcompat:appcompat:1.0.0'
    implementation 'com.alibaba:fastjson:1.2.83'
    implementation 'com.facebook.fresco:fresco:1.13.0'
    implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
    implementation("com.google.firebase:firebase-analytics")
}

如果不知道如何更改,依然可以复制官方封装好的插件里面的对应文件自行更改即可

接下来开始编写我们自己的插件代码

因为我已经实现了这个插件后再编写的记录文章,有些地方难免会站在上帝视角

src/main/java/xxxxxxx 文件夹下新增文件

因为在封装firebase-analytics插件中,我们需要用到 context,所以新建 MyApplication.java 文件,用于 context 的获取(文件名字自己随便取)

MyApplication.java

package com.meditation.uni_firebase_plugin;

import android.app.Application;
import android.content.Context;

import com.google.firebase.FirebaseApp;

public class MyApplication extends Application {
    private static Context context;

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化firebase
        FirebaseApp.initializeApp(this);
        // 保存context
        context = getApplicationContext();
    }
    public static Context getContext() {
        return context;
    }
}

注册MyApplication(对于Android大佬来说这个就很简单了),更改 src/main/AndroidManifest.xml 文件(顺便把需要的权限一并搞了)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 需要的权限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <!-- 注册 MyApplication -->
    <application
        android:name="com.meditation.uni_firebase_plugin.MyApplication">
    </application>

</manifest>

继续回到我们的主题上,在 src/main/java/xxxxxxx 新建 UniFirebaseAnalytics.java 文件

UniFirebaseAnalytics.java

package com.meditation.uni_firebase_plugin;

import android.os.Bundle;
import androidx.annotation.NonNull;

import com.alibaba.fastjson.JSONObject;
import com.google.firebase.analytics.FirebaseAnalytics;

import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.common.UniModule;

public class UniFirebaseAnalytics extends UniModule {
    // 保存FirebaseAnalytics实例,后面会用
    private final FirebaseAnalytics mFirebaseAnalytics = FirebaseAnalytics.getInstance(MyApplication.getContext());

    /**
     * 事件上报
     * @param eventName 事件名称
     * @param paramKey 事件的key
     * @param paramValue 事件的value
     */
    public void logEvent(String eventName, @NonNull String paramKey, String paramValue) {
        mFirebaseAnalytics.logEvent(eventName, getBundle(paramKey, paramValue));
    }

    private Bundle getBundle(String paramKey, String paramValue) {
        Bundle params = new Bundle();
        params.putString(paramKey, paramValue);
        return params;
    }

    // 给uniapp中调用的方法,只是简单实现了一下,可以根据实际情况更改
    // 该方法只接收一个事件名称参数(eventName),预留的key和预留的value可以自行参数化
    @UniJSMethod(uiThread = true)
    public void baseEvent(JSONObject options, UniJSCallback callback) {
        // 接收uniapp那边传递过来的参数
        String eventName = (String) options.get("eventName");
        logEvent(eventName, "这是预留的上报事件key", "这是预留的上报事件value");

        // 给uniapp那边说一声我们调用成功了
        if(callback != null) {
            JSONObject data = new JSONObject();
            data.put("code", "200");
            data.put("message", "success");
            callback.invoke(data);
        }
    }
}

然后更改 根目录下 app/src/main/assets/dcloud_uniplugins.json 文件,按照这个文件里面有的内容格式将我们自己的插件信息加入到里面就行了

"nativePlugins": [
  // ... 其他省略,新增我们自己插件的信息
  {
    "hooksClass": "",
    "plugins": [
      {
        "type": "module",
        "name": "UniFirebasePlugin",
        "class": "com.meditation.uni_firebase_plugin.UniFirebase"
      }
    ]
  }
]

接下来打包生成 arr 文件就行了,在android studio 的右边。找到大象图标,点击展开这个选项卡,找到我们自己的插件文件夹,在这个插件文件夹下找到 Tasks/other/assembleRelease, 双击这个文件等待打包完成即可

image02.png

生成的路径应该自己能够找到吧,在对应的build文件夹里面,将打包好的这个复制到我们自己的uniapp项目中使用即可

image03.png

好了,上面简单实现了一个事件上报,后续要新增其他功能按照这个思路来就行了,接下来我们取使用这个插件

使用插件

回到uniapp中,在项目根目录新建 nativeplugins/插件名称/android/ 文件夹,用于存放我们的原生插件

将刚才打包好的 arr 文件复制到这个文件夹下。

nativeplugins/插件名称/ 目录下新建 package.json 文件,用于填写插件描述信息

{
    "name": "UniFirebasePlugin",
    "id": "UniFirebasePlugin",
    "version": "1.0",
    "description": "插件描述",
    "_dp_type":"nativeplugin",
    "_dp_nativeplugin": {
        "android": {
            "plugins": [
                {
                 "type": "module",
                 "name": "UniFirebasePlugin",
                 "class": "com.meditation.uni_firebase_plugin.UniFirebase"
                }
            ],
            "integrateType": "aar",
            "minSdkVersion": "33"
        }
    }
}

image04.png

在 uniapp 中找到 manifest.json 文件,点击 App原生插件配置,选择本地插件

在项目中使用

<script>
  const firebasePlugin = uni.requireNativePlugin("UniFirebasePlugin")

  export default {
    // 其他代码省略...
    onShow() {
      firebasePlugin.baseEvent({
				"eventName": "testShowPage"
			}, res => {
        console.log(res)
      })
    }
  }
</script>

至此就完成了(数据可能在24小时后才能看到...)。