yalcin-ata / godot-android-plugin-firebase Goto Github PK
View Code? Open in Web Editor NEWGodot 3.2.2 Android plugin for Firebase
Godot 3.2.2 Android plugin for Firebase
Firebase Analytics had manual screen view tracking quit messed up until recently.
Before:
They have the predefined screen_view
, but you would get an error if trying to manually send it. You should use setScreenName()
, but it had the issue that, due to automatic activity tracking, two screen_view
events would get logged. (setScreenName()
was not anyway exposed in this plugin. Just mentioning it to tell the whole story.)
Now:
They deprecated setScreenName()
and now you can submit screen_view
events manually, which gets us rid of the mentioned issues. For that to work, you need Firebase Analytics 17.5.0.
My request is therefore to upgrade the relevant library, like this:
com.google.firebase:firebase-analytics:17.5.0
I've done it for my game and it's working fine.
By the way, since I'm only using Analytics, that's actually the only entry I've left in Firebase.release.gdap
. I've even removed androidx.work:work-runtime:2.3.4
and com.google.guava:guava:29.0-android
since they don't seem to be needed, at least for it. Are they really needed for the other Firebase packages?
I take the opportunity to thank you for this Firebase integration. It works fine and saves a lot of time.
Hello sir,
Could you provide a documentation for using your plugin with the C# language as it is fully functional in the 3.2.2 release of godot?
Thanks in advance.
admob banner is invisibly shown, we have to click on the ad banner first, then it will show.
I don't know where to submit this, and this repository has been very useful for me. Firebase Cloud Messaging worked like a charm!, but a few things happened before.
I would love if this repository is more visible and more updated by @yalcin-ata ... But I know that every person has it's own business and stuff to do.
These questions are some things that I was able to fix by myself. (In addition to the get_token() method.)
For this, you need to edit your AndroidManifest.xml and then compile following this steps to look like this:
If you want to understand what you are doing read this documentation from Firebase.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application>
<!-- How to show custom icon in the notification? -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
<!-- Does not change. -->
<meta-data
android:name="org.godotengine.plugin.v1.Firebase"
android:value="org.godotengine.androidplugin.firebase.Firebase" />
<!-- How to receive Firebase Cloud Messaging callbacks? -->
<service
android:name="org.godotengine.androidplugin.firebase.CloudMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
Is it possible to add remote firebase configuration in this plugin? I have a project that would need this function but unfortunately I don't understand anything about Java to do this implementation, thanks.
Hi @yalcin-ata, I wanted to ask you if you have plans to implement Google Play Games Services in your plugin?
Would be really useful with support for audio level control, like this: https://developers.google.com/admob/android/global-settings
Especially important to be able to mute ad sound volume.
Great plugin by the way!
Events like the predefined tutorial_begin
have no arguments, so they can be logged with a null
Bundle
, but this check is preventing it:
My workaround so far is sending a dummy Dictionary
, like { "_": "" }
.
Ideally, the method should allow null
and empty Dictionary
.
Hey Yalcin, good night! Can you help me with that?
Everythings works fine, but when a send a push notification received a notifi with a gray icon, and i dont find a solution!
Will godot 3.5+ support come?
Hey,
I've forked your project, removed everything except analytics and authentication, rebuild it and exported my godot project.
The export itself succeeds, but the app crashes on startup:
2020-07-19 14:58:06.448 12724-12724/com.godot.game W/FirebaseApp: Default FirebaseApp failed to initialize because no default options were found. This usually means that com.google.gms:google-services was not applied to your gradle project.
2020-07-19 14:58:06.448 12724-12724/com.godot.game I/FirebaseInitProvider: FirebaseApp initialization unsuccessful
2020-07-19 14:58:06.600 12724-12724/com.godot.game I/GodotPluginRegistry: Initializing Godot plugin Firebase
2020-07-19 14:58:06.609 12724-12724/com.godot.game I/GodotPluginRegistry: Completed initialization for Godot plugin Firebase
2020-07-19 14:58:08.841 12724-12724/com.godot.game W/FirebaseApp: Default FirebaseApp failed to initialize because no default options were found. This usually means that com.google.gms:google-services was not applied to your gradle project.
2020-07-19 14:58:08.842 12724-12724/com.godot.game D/Firebase: Analytics initializing
2020-07-19 14:58:08.883 12724-12724/com.godot.game D/Firebase: Analytics initialized
2020-07-19 14:58:08.883 12724-12724/com.godot.game D/Firebase: Authentication initializing
2020-07-19 14:58:08.893 12724-12724/com.godot.game D/AndroidRuntime: Shutting down VM
2020-07-19 14:58:08.895 12724-12724/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.godot.game, PID: 12724
java.lang.IllegalArgumentException: Given String is empty or null
at com.google.android.gms.common.internal.Preconditions.checkNotEmpty(com.google.android.gms:play-services-basement@@17.1.1:5)
at com.google.android.gms.auth.api.signin.GoogleSignInOptions$Builder.zac(com.google.android.gms:play-services-base@@17.1.0:55)
at com.google.android.gms.auth.api.signin.GoogleSignInOptions$Builder.requestIdToken(com.google.android.gms:play-services-base@@17.1.0:29)
at org.godotengine.androidplugin.firebase.AuthenticationGoogle.init(AuthenticationGoogle.java:68)
at org.godotengine.androidplugin.firebase.Authentication.init(Authentication.java:52)
at org.godotengine.androidplugin.firebase.Firebase.initFirebase(Firebase.java:169)
at org.godotengine.androidplugin.firebase.Firebase.access$100(Firebase.java:37)
at org.godotengine.androidplugin.firebase.Firebase$1.run(Firebase.java:129)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Note: google-services and firebase plugin json files are included in the export per instructions
I followed all the steps in your instruciton, especially adding dep to google-services and applying google-services plugin in android/build/build.gradle:
sed "/^\/\/CHUNK_BUILDSCRIPT_DEPENDENCIES_BEGIN.*/a classpath 'com.google.gms:google-services:4.3.3'" -i android/build/build.gradle
sed "/^\/\/CHUNK_GLOBAL_BEGIN.*/a apply plugin: 'com.google.gms.google-services'" -i android/build/build.gradle
This results in:
diff --git a/android/build/build.gradle b/android/build/build.gradle
index f1fd716c..a161abe9 100644
--- a/android/build/build.gradle
+++ b/android/build/build.gradle
@@ -17,6 +17,7 @@ buildscript {
classpath libraries.androidGradlePlugin
classpath libraries.kotlinGradlePlugin
//CHUNK_BUILDSCRIPT_DEPENDENCIES_BEGIN
+classpath 'com.google.gms:google-services:4.3.3'
//CHUNK_BUILDSCRIPT_DEPENDENCIES_END
}
}
@@ -115,6 +116,7 @@ android {
// Both signing and zip-aligning will be done at export time
buildTypes.all { buildType ->
+resValue "string", "server_client_id", "######"
buildType.zipAlignEnabled false
buildType.signingConfig null
}
@@ -163,4 +165,5 @@ android {
}
//CHUNK_GLOBAL_BEGIN
+apply plugin: 'com.google.gms.google-services'
//CHUNK_GLOBAL_END
Not sure if it's relevant, but after successful export, the apply plugin google-services is missing from build.gradle (along with some other stuff too):
root@557ece530399:/dungeon-puzzle# godot --quiet --export-debug "Android" export/debug.apk
root@557ece530399:/dungeon-puzzle# echo $?
0
root@557ece530399:/dungeon-puzzle# git diff
diff --git a/android/build/build.gradle b/android/build/build.gradle
index f1fd716c..ec454fd4 100644
--- a/android/build/build.gradle
+++ b/android/build/build.gradle
@@ -115,6 +115,7 @@ android {
// Both signing and zip-aligning will be done at export time
buildTypes.all { buildType ->
+resValue "string", "server_client_id", "######"
buildType.zipAlignEnabled false
buildType.signingConfig null
}
I've run out of ideas. Does this ring a bell? What should I double-check next?
I want to upload my files in different folder in firebase storage but I don't know how to do this with this plugin.
Can you please inform me how to create a folder in firebase storage using this plugin and how to upload files to that folder.
I have recently installed the Ubuntu OS and tried to export my project through it on android. But i dont now why the Firebase plugin is not working on Ubuntu which is working fine on windows.
How do I set the name of a document in a collection and retrieve that specific document from a collection?
using Godot;
using Godot.Collections;
using System;
using Object = Godot.Object;
public class FirebaseManager : Node
{
public static FirebaseManager instance;
private Object Firebase;
bool initState = false;
bool isBannerLoaded = false;
Vector2 bannerSize = Vector2.Zero;
bool isInterstitialLoaded = false;
bool isRewardedVideoLoaded = false;
float gameTimeScale = 0;
public event FirebaseEvent<Vector2> onBannerActivity;
uint lastConnectionTry = 0;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
instance = this;
if (OS.GetName() == "Android")
{
InitFirebase();
}
gameTimeScale = Engine.TimeScale;
}
public override void _Process(float delta)
{
if (OS.GetName() == "Android")
{
if (!initState)
{
if ((OS.GetTicksMsec() - lastConnectionTry) > 10)
{
lastConnectionTry = OS.GetTicksMsec();
InitFirebase();
}
}
}
}
private void InitFirebase()
{
if (Firebase != null)
{
Firebase.Call("init", GetInstanceId());
initState = true;
// Autentication
if((bool)Firebase.Call("authentication_google_is_connected") == false){
Firebase.Call("authentication_google_sign_in");
}
}
else
{
Firebase = Engine.GetSingleton("Firebase");
Firebase.Call("init", GetInstanceId());
initState = true;
// Autentication
if((bool)Firebase.Call("authentication_google_is_connected") == false){
Firebase.Call("authentication_google_sign_in");
}
}
}
//Firebase implementation
public void _on_firebase_receive_message(string tag, string from, object key, object data)
{
GD.Print($"TAG: {tag} || From: {from} || Key: {key} || Data: {data}");
switch (from)
{
case "AdMob":
switch ($"{key}")
{
case "Banner":
ReceivedBanner(data);
break;
case "Interstitial":
ReceivedInterstitial(data);
break;
case "RewardedVideo":
ReceivedRewardedVideo(data);
break;
}
break;
}
}
public void AnalyticSendEvents(string eventName, Dictionary dictionary)
{
Firebase.Call("analytics_send_events", eventName, dictionary);
}
public void AnalyticsSendCustomEvent(string someKey, string someValue)
{
Firebase.Call("analytics_send_custom", someKey, someValue);
}
private void ReceivedBanner(object data)
{
/*
tag=Firebase from=AdMob key=Banner data=on_ad_loaded
tag=Firebase from=AdMob key=Banner data=on_ad_failed_to_load:errorCode
*/
string dataStr = (string)data;
string[] split = dataStr.Split(':');
switch (split[0])
{
case "on_ad_loaded":
isBannerLoaded = (bool)Firebase.Call("admob_banner_is_loaded");
if (isBannerLoaded)
{
// I send the banner measurements through an event.
var bz = (Dictionary)Firebase.Call("admob_banner_get_size");
var x = (int)bz["width"];
var y = (int)bz["height"];
//GD.Print($"Banner size x = {x} || Banner size y {y}");
Firebase.Call("admob_banner_show", true);
onBannerActivity?.Invoke(new Vector2(x, y));
}
break;
case "on_ad_failed_to_load":
// Send an event with the load failure
isBannerLoaded = false;
switch (split[1])
{
case "0":
initState = false;
break;
}
GD.Print($"Banners error {split[1]}");
Firebase.Call("admob_banner_show", false);
onBannerActivity?.Invoke(Vector2.Zero);
break;
}
}
private void ReceivedInterstitial(object data)
{
/*
tag=Firebase from=AdMob key=Interstitial data=on_ad_loaded
tag=Firebase from=AdMob key=Interstitial data=on_ad_failed_to_load:errorCode
tag=Firebase from=AdMob key=Interstitial data=on_ad_closed
*/
string dataStr = (string)data;
string[] split = dataStr.Split(':');
switch (split[0])
{
case "on_ad_loaded":
// Show and pause the game
isInterstitialLoaded = true;
break;
case "on_ad_failed_to_load":
// Send an event with the load failure
switch (split[1])
{
case "0":
initState = false;
break;
}
isInterstitialLoaded = false;
break;
case "on_ad_closed":
// Reanudar el juego
isInterstitialLoaded = false;
break;
}
}
private void ReceivedRewardedVideo(object data)
{
/*
tag=Firebase from=AdMob key=RewardedVideo data={status:on_rewarded_ad_loaded, unit_id:ca-app-pub-AD_UNIT_ID}
tag=Firebase from=AdMob key=RewardedVideo data={status:on_rewarded_ad_failed_to_load:errorCode, unit_id:ca-app-pub-AD_UNIT_ID}
tag=Firebase from=AdMob key=RewardedVideo data={status:earned, rewardType, rewardAmount, unit_id:ca-app-pub-AD_UNIT_ID}
tag=Firebase from=AdMob key=RewardedVideo data={status:closed, unit_id:ca-app-pub-AD_UNIT_ID}
*/
Dictionary dataDict = (Dictionary)data;
string status = (string)dataDict["status"];
string[] split = status.Split(':');
switch (split[0])
{
case "on_rewarded_ad_loaded":
GD.Print($"Status = {split[0]}");
isRewardedVideoLoaded = true;
break;
case "on_rewarded_ad_failed_to_load":
switch (split[1])
{
case "0":
initState = false;
break;
}
GD.Print($"Status = {split[0]}:{split[1]}");
isRewardedVideoLoaded = false;
break;
case "earned":
GD.Print($"Status = {split[0]}");
isRewardedVideoLoaded = false;
break;
case "closed":
GD.Print($"Status = {split[0]}");
isRewardedVideoLoaded = false;
break;
}
}
}
public delegate void FirebaseEvent<T>(T data);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.