1. Hey! Guest! The 33rd GMC Jam will take place between May 23rd, 12:00 UTC (Friday noon) and May 27th, 12:00 UTC (Monday noon). Why not join in! Click here to find out more!
    Dismiss Notice

Android Gradle build with Google Firebase

Discussion in 'GameMaker Studio 2 Community Tech Support' started by clee2005, Jun 22, 2018.

  1. clee2005

    clee2005 Member

    Joined:
    Jun 25, 2016
    Posts:
    190
    I managed to get Firebase Crashlytics to build but I have to put the "google-services.json" in the android/runner/project folder for it to get picked up by the build. This is fine for this one app... I'd rather not have to switch this file out for each build of different apps. Is there a place to put this file where it will belong to the GMS2 project and get seen by the Gradle build?

    Thanks,
    Chris
     
  2. Mert

    Mert Member

    Joined:
    Jul 20, 2016
    Posts:
    262
    I'll just up this topic, exactly needed
     
    Animus Audax likes this.
  3. clee2005

    clee2005 Member

    Joined:
    Jun 25, 2016
    Posts:
    190
    I have another issue where I have api_key.txt for Amazon Login. I'm using it for Amazon Underground and Amazon App store. I need to swap this file out in the Included Files folder of the IDE before each build since it's the same filename. What would be nice is a pre-build macro or process that could be kicked off... simple as executing a batch file or something before the build is run ... this could solve both problems and many others I'm sure.
     
  4. Animus Audax

    Animus Audax Member

    Joined:
    Nov 27, 2018
    Posts:
    2
    Anybody solved this issue with swapping "google-services.json" ?
    Maybe it's possible to change names that Firebase is looking for?
     
  5. Mert

    Mert Member

    Joined:
    Jul 20, 2016
    Posts:
    262
    I've successfully ported Crashlytics and Performance Monitoring along with Remote Configurations, Analytics and Firestore. Also be impletementing Machine Learning kits once I have some free time.

    Currently, there's no way to change google-services.json file on GMS2 IDE. You'd have to manually put it on (The folder is for me, but should be same for you too) Program Data folder is hidden, so you have to set Windows to see hidden files.

    C:/Program Data/GameMakerStudio2/Cache/runtimes/runtime-2.2.0.261/android/runner/ProjectFiles/

    Check the runtime you use on GMS2 IDE, that's the folder you're going to put it on.
     
    Animus Audax likes this.
  6. Mert

    Mert Member

    Joined:
    Jul 20, 2016
    Posts:
    262
    ++
    Things so far I've discovered.

    ANALYTICS
    When I switch to another room in my app, Firebase logs that as "user_engagement" as if it switches to another Activity. (perhaps it does). I want to set the current screen to log in Firebase, but Game Maker creates random screen ID for each room, just makes the analytics too unreadable for this. Firebase docs implies that you can set screens manually, but has to be called from Main Thread. Here's how I did that. Put it on Room's Creation Code.

    AnalyticsSetCurrentScreen("Main Menu"); for example

    mFirebaseAnalytics is set when I call the function AnalyticsInit
    Code:
    public void AnalyticsSetCurrentScreen(final String arg0) {
        
            RunnerActivity.CurrentActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
              mFirebaseAnalytics.setCurrentScreen(RunnerActivity.CurrentActivity, arg0, null);
            }//public void run() {
            });
        }
    However, it logs two events on analytics. One : When Game Maker changes the room(with random room ID), and this one where you can see screen name properly. Not looks neat, but does the job. Best option is to avoid changing rooms(use one room throughout the game)

    PERFORMANCE MONITORING
    It can track basics, like network timing and the time it takes to open the application etc. I can't do custom traces since Game Maker builds the game with its library, and anything you put on, let's say CREATE EVENT, may be put on another part of the final java file. I'll need more information from Yoyogames about how Yoyogames do these stuff.

    CRASHLYTICS
    Game Maker doesn't use proguard, so I wouldn't need mapping etc. The only issue with this is that we don't have try <> catch <> exception, as Crashlytics can capture exceptions and log those on Firebase panel. Even though I've seen posts from Yoyogames to bring exception to Game Maker, I don't know whether we can use this feature with Crashlytics.

    REMOTE CONFIGURATIONS
    All works perfectly. The only issue is the tiny tiny data conversion issue where Game Maker can only pass either string or double to/from java file. I use long and boolean too. I have Social Async call once the remote configurations are loaded, and can get these values non-async.

    CLOUD MESSAGING
    I've managed to receive Cloud Messages from Firebase panel to Game Maker, but didn't have much time to do further. I'm planning to complete it and get notifications etc.

    EDIT : I've managed to send remote push notifications successfully. It also tracks how many devices received the notification and how many of them opened it.

    CLOUD STORAGE
    Must not be too hard, also on my list.

    EDIT : FIRESTORE
    Basically the easiest one I've approached. I successfully implemented real-time document listening so I receive updates(almost instantly although I live in Turkey and the database is in US-Central). I can therefore do something like chat application or turn based games.

    I am planning to create a tutorial here. I also currently use Firebase remote configurations and features in my Android app Flax
     
    Last edited: Jan 28, 2019
    Animus Audax and Justice like this.
  7. clee2005

    clee2005 Member

    Joined:
    Jun 25, 2016
    Posts:
    190
    @Mert thanks for this posting! I was looking for details on the screen name in Firebase.

    I also rigged up a .vbs scripting setup for my apps which allows me to switch out the Firebase google-services.json and GoogleService-info.plist (iOS) as well as any other changes to the GMS runtimes that are needed. I installed a PS Hot Launch utility which allows me to run the .vbs script via CTRL-F12 (or anything you want to hotkey). So I do this just before I build and it brings up a little menu in .vbs script where I choose the app I'm building and it swaps everything as needed. This will do until YoYo adds the ability to inject pre-build changes of our own.

    Main Script
    Code:
    dim runtime,androidRootFiles,androidProjectSourceMain,androidProjectXML,rootPath,isAmazon,androidProjectFiles,admobAppId
    runtime = "2.2.1.291"
    
    if WScript.Arguments.Count = 0 then
        WScript.Echo "Missing parameters"
        wscript.quit
    end if
    
    Const ForReading = 1
    Const ForWriting = 2
    
    androidRootFiles = "C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-" & runtime & "\android\runner\RootFiles"
    androidProjectSourceMain = "C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-" & runtime & "\android\runner\ProjectFiles\src\main"
    androidProjectFiles = "C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-" & runtime & "\android\runner\ProjectFiles"
    androidProjectXML = "C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-" & runtime & "\android\runner\ProjectFiles\src\main\res\xml"
    androidRunner = "C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-" & runtime & "\android\runner\ProjectFiles\src\main\java\YYAndroidPackageDomain\YYAndroidPackageCompany\YYAndroidPackageProduct"
    iosProjectRoot = "C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-" & runtime & "\ios\TemplateProject\${YYXCodeProjName}"
    iosProjectFile = "C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-" & runtime & "\ios\TemplateProject\${YYXCodeProjName}.xcodeproj"
    iosFoldersRoot = "C:\ProgramData\GameMakerStudio2\Cache\runtimes\runtime-" & runtime & "\ios\TemplateProject"
    
    rootPath = WScript.Arguments(0)    ' The Path of the GMS projet where the expected files exist
    isAmazon = WScript.Arguments(1)       ' If True indicates we are building for the Amazon store
    admobAppId = WScript.Arguments(2)  ' The Admob ID to update the Appodeal manifest
    langs = WScript.Arguments(3)       ' The iOS languages to support 'ES,FR'
    
    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    dim scriptdir
    scriptdir = fso.GetParentFolderName(WScript.ScriptFullName)
    
    ' If the network_security_config.xml file is not in place then run the following one time copy instructions
    If (not Fso.FileExists(androidProjectXML & "\network_security_config.xml")) Then
       
        ' Copy Resources folder for Appodeal
        Fso.CopyFolder scriptdir & "\Resources", iosFoldersRoot & "\Resources"  
       
        ' Copy the network_security_config.xml and AndroidManifest.xml
        Fso.CopyFile scriptdir & "\network_security_config.xml", androidProjectXML & "\network_security_config.xml"
        Fso.CopyFile scriptdir & "\AndroidManifest.xml", androidProjectSourceMain & "\AndroidManifest.xml"
       
        ' Create the French and Spanish languages (even though we may only use one or both)
        Fso.CopyFolder iosProjectRoot & "\en.lproj", iosProjectRoot & "\es.lproj"
        Fso.CopyFolder iosProjectRoot & "\en.lproj", iosProjectRoot & "\fr.lproj"
       
        ' Copy modifications to the Android Runner
        Fso.CopyFile scriptdir & "\RunnerActivity.java", androidRunner & "\RunnerActivity.java"
       
        MsgBox("Copied : " + chr(13) + "RunnerActivity.java" + chr(13) + "Appodeal Resources folder" + chr(13) + "network_security_config.xml" + chr(13) + "AndroidManifest.xml" + chr(13) + "fr.lproj (ios)" + chr(13) + "es.lproj" + chr(13) + "Runtime : " & runtime )
           
    end if
    
    ' Copy the gradle modified files
    Fso.CopyFile scriptdir & "\root-build.gradle", androidRootFiles & "\build.gradle"
    Fso.CopyFile scriptdir & "\project-build.gradle", androidProjectFiles & "\build.gradle"
    
    ' Modify the Appodeal manifest which includes the ADMOB ApplicationID
    dim first,second
    Set objFile = Fso.OpenTextFile(rootPath & "\extensions\AppodealAds\AppodealAds.yy", ForReading)
    strText = objFile.ReadAll
    objFile.Close
    first = Left(strText,InStr(strText,"ca-app-pub-XXXXXXX~")-1) ' This is the admob id which is the same for all apps replace XXXXXXX with your actual admob publisher id
    second = Mid(strText,InStr(strText,"ca-app-pub-XXXXXX~"))
    second = Mid(second, InStr(second,"\"))
    strNewText = first & admobAppId & second
    Set objFile = Fso.OpenTextFile(rootPath & "\extensions\AppodealAds\AppodealAds.yy", ForWriting)
    objFile.WriteLine strNewText
    objFile.Close
    
    
    '''''''''''''''''
    ' iOS
    '''''''''''''''''
    
    ' Copy the GoogleService-Info.plist to iOS
    Fso.CopyFile rootPath & "\GoogleService-Info.plist", iosProjectRoot & "\GoogleService-Info.plist"
    
    ' Copy the project.pbxproj to iOS - Then modify to replace the languages to be used
    Fso.CopyFile scriptdir & "\project.pbxproj", iosProjectFile & "\project.pbxproj"
    Set objFile = Fso.OpenTextFile(iosProjectFile & "\project.pbxproj", ForReading)
    strText = objFile.ReadAll
    objFile.Close
    strNewText = Replace(strText, "${AdditionalLanguages}", langs)
    Set objFile = Fso.OpenTextFile(iosProjectFile & "\project.pbxproj", ForWriting)
    objFile.WriteLine strNewText
    objFile.Close
    
    
    ' Get Project Folder Name
    dim projectName,store
    projectName = Fso.getfolder(rootPath).Name
    
    if (isAmazon) then
        Fso.CopyFile rootPath & "\google-services-amazon.json", androidProjectFiles & "\google-services.json"
       
        ' Copy the Amazon Login api_key
        Fso.CopyFile rootPath & "\api_key_amazon.txt", rootPath & "\datafiles\api_key.txt"
       
        store = "AMAZON"
    else
        Fso.CopyFile rootPath & "\google-services.json", androidProjectFiles & "\google-services.json"
       
        ' Copy the Amazon Login api_key
        Fso.CopyFile rootPath & "\api_key_googleplay.txt", rootPath & "\datafiles\api_key.txt"
       
        store = "Google Play"
    end if
    MsgBox("Project : " & projectName & chr(13) & "Runtime : " & runtime & chr(13) & chr(13) & "Android : " & store)
    
    
    Then in each project folder (where the google-services.json and other specific files are expected to be) you'll have this .vbs which sends the specific information to the above script.

    Code:
    ' This is the specific script to be launched from each project folder
    Dim fso,admobAppId,parentFolder,scriptdir
    admobAppId = "ca-app-pub-XXXXX~XXXXXX"
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    scriptdir = fso.GetParentFolderName(WScript.ScriptFullName)
    parentFolder = fso.GetParentFolderName(scriptdir)
    
    Dim objShell
    Set objShell = Wscript.CreateObject("WScript.Shell")
    
    ' Params
    ' 1 - This script path
    ' 2 - IsAmazon Build (true/false)
    ' 3 - Admob App ID
    ' 4 - Languages supported (fr,es)
    
    objShell.Run parentFolder + "\Build\SetGMSBuild.vbs " & scriptdir & " false " & admobAppId & " fr,es,"
    
    ' Using Set is mandatory
    Set objShell = Nothing
    Then you just need to call the project specific .vbs file right before you build and it'll ensure that your runtime is ready to go. Also when YoYo updates the Runtime this same script will ensure that all the alterations to the Runtime (long term modifications) are put back in place. I'm using Appodeal for mediation so I have changes for that and for iOS additional languages to the XCode project. Just remove those as you see fit.

    I hope some of that is useful to someone.

    Cheers,
    Chris
     
    Last edited: Feb 19, 2019
    Mert likes this.
  8. Mert

    Mert Member

    Joined:
    Jul 20, 2016
    Posts:
    262
    @clee2005 thanks, sounds absolutely delicious!

    I'll also work on Machine Learning kits (perhaps the visualise tools first). My intention is to make a game that is something like;
    • You get a keyword of an object/animal/food anything.. (Pencil for example)
    • You must draw this on screen to explain it to other players.
    • Check the screen if it looks like pencil(I have zero idea if currently premade tools are capable of doing this, but they should be)
    • If it checks, award the player a point.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice