B4A Library {Donationware} Firebase Appinvite

This library is Donationware!
You can download the library, you can test the library.

But if you want to USE the library in your App you need to Donate at least $10 for it.

Please click here to donate for my work to write the wrapper (You can donate any amount you want :) but the minimum donation should be $10 for this Library)



This i a wrap around the Firebase Appinvite

Firebase Invites are an out-of-the-box solution for app referrals and sharing via email or SMS. To customize the invitation user experience, or to generate links programmatically, use Firebase Dynamic Links.


Word of mouth is one of the most effective ways of getting users to install your app. In a recent study of thousands of smartphone users, researchers found that the #1 reason people discovered an app is because they heard about it from a friend or colleague. Firebase Invites makes it easy to turn your app's users into your app's strongest advocates.
Firebase Invites builds on Firebase Dynamic Links, which ensures that recipients of links have the best possible experience for their platform and the apps they have installed.

How does it work?
When a user taps one of your app's Share buttons and chooses the Firebase Invites channel—usually named "Email and SMS"—the Firebase Invites sharing screen opens. From the sharing screen, the user selects recipients from their Google contacts and contacts stored locally on the device, optionally customizes the invitation message and sends the invitations. Invitations are sent by email or SMS, depending on the available contact information, and contain a Dynamic Link to your app.

When the invitation's recipients open the Dynamic Link in the invitation, they are sent to the Play Store or App Store if they need to install your app; then, your app opens and can retrieve and handle the link.

Requirements:
- SDK Manager V2.20+: https://www.b4x.com/android/forum/threads/gui-sdk-manager-for-newer-versions-of-android-tools.80090
- You need to add Firebase to your app. See this Tutorial on how to add the needed Snippets.

FirebaseAppInvite

Author: DonManfred
Version:
1.2
  • AppInviteInvitationBuilder
    • Events:
      • onInvite (invites As List)
    • Functions:
      • build
      • Initialize (EventName As String, title As String)
      • setOtherPlatformsTargetApplication (arg0 As Int, arg1 As String)
    • Properties:
      • AdditionalReferralParameters As Map [write only]
      • CallToActionText As CharSequence [write only]
      • CustomImage As String [write only]
      • DeepLink As String [write only]
      • EmailHtmlContent As String [write only]
      • EmailSubject As String [write only]
      • GoogleAnalyticsTrackingId As String [write only]
      • Message As CharSequence [write only]
  • DynamicLink
    • Functions:
      • getBooleanQueryParameter (key As String, defaultValue As Boolean) As Boolean
      • Initialize (dl As com.google.firebase.dynamiclinks.DynamicLink)
      • IsInitialized As Boolean
    • Properties:
      • Authority As String [read only]
      • EncodedAuthority As String [read only]
      • EncodedFragment As String [read only]
      • EncodedPath As String [read only]
      • EncodedQuery As String [read only]
      • EncodedSchemeSpecificPart As String [read only]
      • EncodedUserInfo As String [read only]
      • Fragment As String [read only]
      • Host As String [read only]
      • LastPathSegment As String [read only]
      • Parameters As Map [read only]
      • Path As String [read only]
      • PathSegments As java.util.List [read only]
      • Port As Int [read only]
      • Query As String [read only]
      • UriStr As String [read only]
  • FirebaseDynamicLinks
    • Events:
      • onBundleInfo (inviteBundle As Map)
      • onComplete (shortlinktask As Object)
      • onDynamicLink (link As Map)
      • onFailure()
      • onShortDynamicLink (link As String)
      • onShortLink (link As String)
    • Functions:
      • BuildDynamicLink As DynamicLink
      • buildShortDynamicLink
      • getBundleFromIntent (intent As android.content.Intent) As Map
      • getDynamicLink (uriString As String)
      • getDynamicLinkFromIntent (intent As android.content.Intent) As com.google.android.gms.tasks.Task
      • getDynamicLinkFromUri (uri As String) As com.google.android.gms.tasks.Task
      • getresult (dynLink As com.google.android.gms.tasks.Task) As com.google.firebase.dynamiclinks.ShortDynamicLink
      • Initialize (EventName As String)
      • setAndroidParameters (FallbackUrl As String, minVersion As Int)
      • setGoogleAnalyticsParameters (Campaign As String, Content As String, Medium As String, Source As String, Term As String)
      • setIosParameters (unknown As String, AppStoreId As String, CustomScheme As String, FallBackUrl As String, iPadBundleId As String, iPadFallbackUrl As String, minVersion As String)
      • setItunesConnectAnalyticsParameters (AffiliateToken As String, CampaignToken As String, ProviderToken As String)
      • setSocialMetaTagParameters (description As String, imageUrl As String, title As String)
    • Properties:
      • DynamicLinkDomain As String [write only]
      • Link As String [write only]
      • LongLink As String [write only]

Sample code to send an Invitation:
B4X:
    fbdl.Initialize("fbdl")
    fbdl.DynamicLinkDomain = "xxxx.app.goo.gl" ' "t62hm.app.goo.gl"
    fbdl.setSocialMetaTagParameters("description", "imageUrl", "title")
    'fbdl.Link = "https://fbdl.basic4android.de/secure/test/"
    fbdl.Link = "https://fbdl.basic4android.de/secure/test/"
  
    ' Seems that we are not allowed to call buildShortDynamicLink to build an shorturl.
    ' We need to go over the Invitatinbuilder i guess....
    ' we cget an Exception = Forbidden at some time after calling this Method
    'fbdl.buildShortDynamicLink
  
    Dim dynlink As DynamicLink = fbdl.BuildDynamicLink
    Log($"#-  x67, strDynamicLink=${dynlink.Parameters}"$)
    For Each key As String In dynlink.Parameters.Keys
        Log($"#-  x67a, ${key}=${dynlink.Parameters.Get(key)}"$)      
    Next
    ' Result from log: #-  x67, strDynamicLink=com.google.firebase.dynamiclinks.DynamicLink@55a21d2

  

    invite.Initialize("Invite","Einladung")
    invite.DeepLink = dynlink.UriStr
    invite.Message = cs.Initialize.Color(0xFF01FF20).Size(20).Append("Einladung AppInvite :-)").PopAll
    invite.EmailHtmlContent = $"This app you NEED: bla bla bla<br>Check this: <a href="%%APPINVITE_LINK_PLACEHOLDER%%">AppInvite</a><br><br>Greetings ;-)"$
    ' When using EmailHtmlContent then you should not use CalltoActionText!
    'invite.CallToActionText = cs.Initialize.Typeface(Typeface.FONTAWESOME).Color(0xFF01FF20).Size(40).Append(Chr(0xF17B) & " Einladung " & Chr(0xF17B)).PopAll
    'Invite_onInvite([888939569991-41fae34e-f62d-4b6c-a7be-947dc90279cb])
    invite.EmailSubject = "B4A AppInvite rocks!"
    'invite.AdditionalReferralParameters = CreateMap("FredoSpecialParameter":"HUHU! :D")
    invite.build
    ToastMessageShow("Message sent", True)

B4X:
Sub Invite_onInvite(invites As List)
    Log($"Invite_onInvite(${invites})"$)
    'http://invite.basic4android.de/?action=addinv&invcode=888939569991-41fae34e-f62d-4b6c-a7be-947dc90279cb&deviceID=ffxxtt&invval=Hellp%20world!!!!
    If invites.IsInitialized Then
        If invites.Size > 0 Then
            For i = 0 To invites.Size -1
                Dim code As String = invites.Get(i)
              
                Dim jgen As JSONGenerator
                jgen.Initialize(CreateMap("Description": "Bla bla bla", "PromoCode": "xyz","PromoID":15))
                Dim j As HttpJob
                j.Initialize("",Me)
                j.Download2("https://cloudbridgeurl",Array As String("action","addinv","invcode",code,"deviceID",Starter.DeviceID,"invval",jgen.ToString))
                Wait For (j) JobDone(job As HttpJob)
                If job.Success Then
                    Log(job.GetString)
                Else
                    Log(job.ErrorMessage)
                End If
                job.Release

            Next
        End If
    End If
End Sub
Sub ParseUri(s As String) As Object
    Dim r As Reflector
    Return r.RunStaticMethod("android.net.Uri", "parse", Array As Object(s), Array As String("java.lang.String"))
End Sub

When a Invitation is send to someone the Event
B4X:
 Invite_onInvite(invites As List)
is raised with a List of all IDs...
You can store the ID for later reference. In my example i store some data about the Invite in the Cloud (my webhosting). I want to read this data later when the user Clicks the Invitationlink in the eMail he got.

NOTE: Firebase Appinvite will start your App (Main Activity) when the User Click n the Link and your app is installed already.
- You need to check if you app is started by an Invitation-link or not.

To do this check you need the following code inside your activity_crate of the main activity:

B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Layout1")
    fbdl.Initialize("fbdl")
    editInvitevalue.Text = ""
    Dim iStart As Intent = Activity.GetStartingIntent
    Log($"#-  intent0, ${iStart}"$)
    edtlog.Text = edtlog.Text&CRLF&iStart      
    If iStart <> Null Then
        Dim task As JavaObject = fbdl.getDynamicLinkFromIntent(iStart)
        Do While task.RunMethod("isComplete", Null) = False
            Log($"#-  intent1, sleep(100)"$)
            edtlog.Text = edtlog.Text&CRLF&"sleep"
            Sleep(100)
          
        Loop
        Log($"#-  intent2, task beendet"$)
      
        Dim invitemap As Map = fbdl.getBundleFromIntent(iStart)
        If invitemap <> Null Then
            Log("InviteMap: "&invitemap)
            Dim values() = Regex.Split("&",invitemap.Get("DEEP_LINK"))
            For Each val As String In values
                If val.StartsWith("link=") Then
                    Dim link As String = su.DecodeUrl(val.SubString(val.IndexOf2("=",0)+1),"utf8")
                    Log(link)
                    'Log(su.DecodeUrl(link,"utf8"))
                End If
                Log("Value: "&val)
            Next
            Dim code As String = invitemap.Get("INVITATION_ID")
            Dim j As HttpJob
            j.Initialize("",Me)
            j.Download2("https://cloudbridgeurl",Array As String("action","getraw","invcode",code,"deviceID",Starter.DeviceID))
            Wait For (j) JobDone(job As HttpJob)
            If job.Success Then
                Log(job.GetString)
                editInvitevalue.Text = job.GetString
                ' {"Description":"Bla bla bla","PromoCode":"xyz","PromoID":15}
            Else
                Log(job.ErrorMessage)
            End If
            job.Release

            edtlog.Text = edtlog.Text&CRLF&iStart.Action
            edtlog.Text = edtlog.Text&CRLF&invitemap
  
            If iStart.Action.Trim.Length <> 0 Then
                Log($" "$)
                Log($"  x28, DeepLinkActivity.Activity_Resume"$)
                'Log($"    x29, iStart.Action=${iStart.Action}"$ )
                'Log($"    x31, getBundleFromIntent=${iStart.ExtrasToString}"$ )
          
                ' ...
            End If
            If link.Trim <> "" Then
                Dim Intent1 As Intent
                Intent1.Initialize2(link, 0)
                Log("Starte Deeplink-LINK")
                Log(link)
                StartActivity(Intent1)
            End If
        End If
    End If

In my case i defined a deeplink of https://fbdl.basic4android.de/secure/test/
Based on this code in the manifest editor
B4X:
AddActivityText(DeepLinkActivity,
        <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>

                <data android:host="fbdl.basic4android.de" android:scheme="http"/>
                <data android:host="fbdl.basic4android.de" android:scheme="https"/>
        </intent-filter>
)
i defined the DeepLinkActivity as the Activity to handle the Link.
B4X:
       If link.Trim <> "" Then
                Dim Intent1 As Intent
                Intent1.Initialize2(link, 0)
                Log("Starte Deeplink-LINK")
                Log(link)
                StartActivity(Intent1)
is just calling the Link....

Note that you dont need to handle the deeplink if you dont want to. Just check the content of the invitemap and extract all data you need parsing the values by yourself.

As this is all you can transfer from the invite to the enduser using the invitation i decided to setup a small SDK to store Invite-data with a invitetoken and to retrieve the data from the cloud if the app is started by an deeplink.

Storing:
B4X:
    If invites.IsInitialized Then
        If invites.Size > 0 Then
            For i = 0 To invites.Size -1
                Dim code As String = invites.Get(i)
              
                Dim jgen As JSONGenerator
                jgen.Initialize(CreateMap("Description": "Bla bla bla", "PromoCode": "xyz","PromoID":15))
                Dim j As HttpJob
                j.Initialize("",Me)
                j.Download2("https://cloudbridgeurl",Array As String("action","addinv","invcode",code,"deviceID",Starter.DeviceID,"invval",jgen.ToString))
                Wait For (j) JobDone(job As HttpJob)
                If job.Success Then
                    Log(job.GetString)
                Else
                    Log(job.ErrorMessage)
                End If
                job.Release

            Next
        End If
    End If

Retrieving the Data after the app is started by a deeplink:
B4X:
            Dim code As String = invitemap.Get("INVITATION_ID")
            Dim j As HttpJob
            j.Initialize("",Me)
            j.Download2("https://cloudbridgeurl",Array As String("action","getraw","invcode",code))
            Wait For (j) JobDone(job As HttpJob)
            If job.Success Then
                Log(job.GetString)
            Else
                Log(job.ErrorMessage)
            End If
            job.Release

The PHP used to store and retrieve data from the cloud is inside the php.zip

The Database is this
-- phpMyAdmin SQL Dump
-- version 3.5.8.1
-- http://www.phpmyadmin.net
--
-- Host: dd12712
-- Erstellungszeit: 08. Okt 2017 um 09:34
-- Server Version: 5.6.33-nmm1-log
-- PHP-Version: 5.5.38-nmm2

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Datenbank: `d027d138`
--

-- --------------------------------------------------------

--
-- Tabellenstruktur für Tabelle `AppInvites`
--

CREATE TABLE IF NOT EXISTS `AppInvites` (
`inv_id` int(11) NOT NULL AUTO_INCREMENT,
`inv_inviteId` varchar(50) NOT NULL DEFAULT '',
`inv_value` text NOT NULL,
`inv_deviceID` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`inv_id`),
UNIQUE KEY `inv_inviteId` (`inv_inviteId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;


This library is Donationware!
You can download the library, you can test the library.

But if you want to USE the library in your App you need to Donate at least $10 for it.

Please click here to donate for my work to write the wrapper (You can donate any amount you want :) but the minimum donation should be $10 for this Library)



Known Issues: For some reason i did not get it to work to let the lib create a SHORT Dynamiclink.

This may help you if you want to share the link by yourself and want use a shorter url. Though is it not really needed if you use the share-method as Firebase is sending the Mail.
 

Attachments

  • php.zip
    20.1 KB · Views: 134
  • FirebaseAppInviteV1.2.zip
    18.5 KB · Views: 138
  • AppInviteEx.zip
    20.5 KB · Views: 133
Last edited:

DonManfred

Expert
Licensed User
Longtime User
Some advice about Firebase AppInvites.

- You need to get rid of an INVITATION_ID and how you want to connect them to a user.
- Keep in Mind that you need to store the INVITATION_ID inside your app (best in the Cloud) so when the invited use click the link and your app is installed then the app get started. You need to recognice the ID by yourself. All you get is inside the DEEPLINK... If you need more Data, find a way yourself to save and rad them based on the INVITATION_ID.
 
Top