Giter Site home page Giter Site logo

pantrist-dev / capacitor-firebase-dynamic-links Goto Github PK

View Code? Open in Web Editor NEW
22.0 22.0 11.0 453 KB

Capacitor Plugin for Firebase Dynamic Links

License: MIT License

Ruby 2.91% Java 3.22% Objective-C 2.35% Swift 32.51% JavaScript 1.31% TypeScript 31.32% Kotlin 26.38%

capacitor-firebase-dynamic-links's People

Contributors

bharaninb avatar chrisweight avatar cwoolum avatar m-scimonelli avatar mauriceackel avatar nlueg avatar zeusmist avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

capacitor-firebase-dynamic-links's Issues

deepLinkOpen not firing when coming back from the app store

Everything is working fine iOS and Android apart from when I don't have the app installed and I come back from the app store.
This works fine with the Playstore.
Using version 1.1.1 of @pantrist/capacitor-firebase-dynamic-links

I am using this method as I don't have the latest version with dynamic links in the app store yet.
I click the short dynamic link and it takes me to the app store and then I run the app from Xcode:
https://stackoverflow.com/questions/39605657/how-can-i-test-firebase-dynamic-links-if-my-app-is-not-in-the-app-store/41050772#41050772

I believe I have implemented all configuration steps. You can see them listed in my stack overflow here:
https://stackoverflow.com/questions/72092939/firebase-short-dynamic-link-not-working-in-ios-being-treated-as-a-deeplink

The FirebaseDynamicLinks.addListener does not raise a link open event

I've encountered a very strange problem...

It would be great if you could help me.

I use capacitor-firebase-dynamic-links version 4.1.0

I have created a short dynamic link, but am having trouble getting it on the application side
I receive the following message on app init.
⚡️ To Native -> CapacitorFirebaseDynamicLinks addListener 121559900

but
FirebaseDynamicLinks.addListener('deepLinkOpen', (data) => {
alert(data.url);
});

does not raise any event .

Could you please let me know what the problem is? Do you have any suggestions on what I should check?

Refards

createDynamicShortLink - Unable to create link

Plugin version - https://www.npmjs.com/package/@pantrist/capacitor-firebase-dynamic-links/v/4.1.0

 const config: LinkConfig = {
              domainUriPrefix: "...",
              uri: uristring,
              androidParameters: {
                packageName:"..."
              },
              iosParameters: {
                bundleId: "...",
                appStoreId:"..."     
              }

createDynamicLink => link getting generrated successfully with above config
but
createDynamicShortLink => getting error as following in only ios platform
{errorMessage: "Unable to create link", message: "Unable to create link"}

during Debugging Dynamic Link getting following warning , not getting any documentation related warning , because of this warning ios createDynamicShortLink failing ?

image

The documentation is a bit unclear on which config steps to perform

The documentation is a bit unclear on which steps to perform here:

iOS
Configure your app to use dynamic links based on the official Firebase documentation. You only need to apply the steps 1-3 of the following guid:

https://firebase.google.com/docs/dynamic-links/ios/receive

I assume it means the first 3 steps here and we ignore steps 4 onward?:
https://firebase.google.com/docs/dynamic-links/ios/receive#open-dynamic-links-in-your-app

In the Info tab of your app's Xcode project, create a new URL type to be used for Dynamic Links. Set the Identifier field to a unique value and the URL scheme field to be your bundle identifier, which is the default URL scheme used by Dynamic Links.

In the Capabilities tab of your app's Xcode project, enable Associated Domains and add the following to the Associated Domains list:

applinks:your_dynamic_links_domain

If you want to receive Dynamic Links with a fully-custom domain, in your Xcode project's Info.plist file, create a key called FirebaseDynamicLinksCustomDomains and set it to your app's Dynamic Links URL prefixes. For example:

FirebaseDynamicLinksCustomDomains

https://example.com/promos
https://example.com/links/share

Is pod 'Firebase/Analytics' really necessary?

Hi there,

I'm using your plugin for quite a while but now I'm having problems on a new project. Having the pod 'Firebase/Analytics' is causing me some weird memory errors when running the app. I found that it was because the pod 'Firebase/Analytics'. After I removed the pod everything went fine and my problem is gone.

For what I tested, everything continues to work even without this pod.

Is there a reason for this pod? Can it be removed (I can create a PR if so)?

Warning about JVM version During Android build phase

Hi have a good day,
I'm getting this warning when building for Android:

'compileDebugJavaWithJavac' task (current target is 11) and 'compileDebugKotlin' task (current target is 1.8) jvm target compatibility should be set to the same Java version.

I understand the JVM version between Kotlin & Java doesn't match.
with Capacitor4, JVM version should be 11 (ref:Capacitor4 Update DOC)

[Capacitor Plugin Error] - createDynamicLink

I'm not getting the long link, using capacitor 4
[Capacitor Plugin Error] - CapacitorFirebaseDynamicLinks - createDynamicLink - Unable to serialize plugin response as JSON.Ensure that all data passed to success callback from module method is JSON serializable!

despite having the log from xcode
⚡️ To Native -> CapacitorFirebaseDynamicLinks createDynamicLink 65776433 The long URL is: {shows the link here}

It works fine on android

iOS - Deep Link does not contain valid required params.

Link is created with function createDynamicShortLink with following linkConfiguration
const config: LinkConfig = {
domainUriPrefix: "https://....",
uri: uristring,
androidParameters: {
packageName: "...."
},
iosParameters: {
bundleId : "...",
appStoreId : "...",
fallbackUrl : "...",
ipadFallbackUrl : "...",
ipadBundleId : "...",
customScheme : "...",
minimumVersion : "...",
}
};

Android - working perfectly
iOS - getting "Deep Link does not contain valid required params." error
Which parameters are missing ?

Also all ios configuration is done by official documents https://firebase.google.com/docs/dynamic-links/ios/receive#open-dynamic-links-in-your-app

Firebase passwordless auth deeplinks aren't working

Spent days on this - really not sure what's wrong...

iOS is able to open deeplinks, and this code in appdelegate is able to see them come in:

`   func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
            // Log the dynamic link or handle the deep link.
            print("Dynamic link detected: \(dynamicLink)")
            return true
        }
        return false
    }`

What I did in a pretty entry point authentication handler:

import { FirebaseDynamicLinks } from '@pantrist/capacitor-firebase-dynamic-links';
...
FirebaseDynamicLinks.addListener('deepLinkOpen', async (data: { url: string }) => {

The links themselves are passwordless authenticator links in the format:
https://domain.page.link/?link=https://domain.com/__/auth/action?apiKey%3Dcode%26mode%3DsignIn%26oobCode%3Dcode%26continueUrl%3Dhttps://domain.com/%26lang%3Den&apn=com.domain.app&amv&ibi=com.domain.app&ifl=https://domain.com/__/auth/action?apiKey%string%26mode%3DsignIn%26oobCode%code%26continueUrl%3Dhttps://domain.com/%26lang%3Den

and are created by:

sendSignInLinkToEmail(FIREBASE_AUTH, email, {
        url: https://domain.com,
        handleCodeInApp: true,
        iOS: {
          bundleId: 'com.domain.app'
        },
        android: {
          packageName: 'com.domain.app',
          installApp: true,
          minimumVersion: '0'
        },
        dynamicLinkDomain: 'domain.page.link'
      });

I even made this plugin update to log where it's failing, but none of this runs.

`    @objc func handleUrlOpened(notification: NSNotification) {
        if let object = notification.object as? [String: Any?] {
            if let url = object["url"] as? URL {
                if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
                    print("Handling dynamic link 1")
                    self.handleLink(dynamicLink)
                } else {
                    print("Some other link case do nothing...")
                    // This is likely to be a custom URL from some other process
                }
            } else {
                print("CapacitorFirebaseDynamicLinks.handleUrlOpened() - url is not of type URL")
            }
        } else {
            print("CapacitorFirebaseDynamicLinks.handleUrlOpened() - object is not of type [String: Any?]")
        }
    }

    @objc func handleUniversalLink(notification: NSNotification) {
        if let object = notification.object as? [String: Any?] {
            if let url = object["url"] as? NSURL {
                if let parsed = URL(string: url.absoluteString!) {
                    let response = DynamicLinks.dynamicLinks().handleUniversalLink(parsed) { (dynamiclink, error) in
                        if let error = error {
                            print("handleUniversalLink -> error: \(String(describing: error.localizedDescription))")
                        } else if let dynamicLink = dynamiclink {
                            print("In universal link 1")
                            self.handleLink(dynamicLink)
                        }
                    }
                    if !response {
                        print("""
                        CapacitorFirebaseDynamicLinks.handleUniversalLink()
                        Unable to parse dynamic link. Please ensure you have set up Firebase Dynamic Links correctly.
                        """)
                    }
                } else {
                    print("CapacitorFirebaseDynamicLinks.handleUniversalLink() - Unable to parse URL")
                }
            } else {
                print("CapacitorFirebaseDynamicLinks.handleUniversalLink() - url is not of type NSURL")
            }
        } else {
            print("CapacitorFirebaseDynamicLinks.handleUniversalLink() - object is not of type [String: Any?]")
        }
    }

    func handleLink(_ dynamicLink: DynamicLink) {
        if let url = dynamicLink.url {
            print("CapacitorFirebaseDynamicLinks.handleLink() - url: \(url.absoluteString)")
            self.notifyListeners("deepLinkOpen", data: ["url": url.absoluteString], retainUntilConsumed: true)
        } else {
            print("CapacitorFirebaseDynamicLinks.handleLink() - Dynamic link has no url")
        }
    }`

[android] NullPointerException caused by missing check for iOS parameters

If you want to create a dynamic short link without providing ios parameters, the app crashes with the following NullPointerException:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.getcapacitor.JSObject.getString(java.lang.String)' on a null object reference
	at com.pantrist.firebase.dynamiclinks.CapacitorFirebaseDynamicLinks.buildIOSParameters(CapacitorFirebaseDynamicLinks.kt:119)
	at com.pantrist.firebase.dynamiclinks.CapacitorFirebaseDynamicLinks.createDynamicShortLink(CapacitorFirebaseDynamicLinks.kt:72)

A solution to this problem would be to add the missing check in CapacitorFirebaseDynamicLinks.kt, that iosParameters is defined properly before trying to access the object:

private fun buildIOSParameters(call: PluginCall, builder: DynamicLink.Builder) {
	val iosParameters = call.getObject("iosParameters")
	
	if (iosParameters != null && iosParameters.getString("bundleId") != null) {
		// ...
	}
}

Change provider-specific values

You should consider to change the provider specific values (i.e. com.turnoutt., etc.) to something specific to you (i.e. com.pantrist.).

This would potentially include changing paths, file names, files themselves, etc.

Unable to import package without SyntaxError

Unable to implement package in my project, seems to be an issue with

SyntaxError: Cannot use import statement outside a module
at compileFunction ()
at wrapSafe (internal/modules/cjs/loader.js:1001:16)
at Module._compile (internal/modules/cjs/loader.js:1049:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
at Module.require (internal/modules/cjs/loader.js:974:19)
at require (internal/modules/cjs/helpers.js:101:18)
at Object.@pantrist/capacitor-firebase-dynamic-links

removeAllListener method is not working on iOS

removeAllListeners() is not working on iOS. It is showing as method not defined.

Same method & code is working perfectly fine on Android.
It is removing all CapacitorDynamicLink listeners in Android.

Can you please check the issue in Plugin

Dynamic short link successfully created and working but not listed on Firebase Dynamic Links

Hello,

I can successfully create dynamic short links with this plugin and I've verified that they work. E.g. I can open the app through a deep link and listen to FirebaseDynamicLinks.addListener("deepLinkOpen", cb).

However, the generated short links are not listed under the Firebase deep links.

Is this expected?

P.S. It's not a matter of delays since I've waited multiple days

Screenshot 2023-11-17 at 12 58 27

[iOS] Trying to figure out, why `deepLinkOpen` was not fired.

Hello,

For some reason, the deepLinkOpen was not fired. I believe, that I did all the configuration required.

Deep-link: https://deep.codesnack-ide.com/app/UkMX


image


image


In my root React component I do:

FirebaseDynamicLinks.addListener('deepLinkOpen', (data) => {
    alert('deepLinkOpen: ' + JSON.stringify(data));
});

// OR

const dynamicLink = await FirebaseDynamicLinks.getDynamicLink();

// dynamicLink - is always null

AppDelegate

import UIKit
import Capacitor
import Firebase
import FBSDKCoreKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        FirebaseApp.configure()

        FBSDKCoreKit.ApplicationDelegate.shared.application(
            application,
            didFinishLaunchingWithOptions: launchOptions
        )

        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
        // Called when the app was launched with a url. Feel free to add additional processing here,
        // but if you want the App API to support tracking app url opens, make sure to keep this call
        if (FBSDKCoreKit.ApplicationDelegate.shared.application(
            app,
            open: url,
            sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
            annotation: options[UIApplication.OpenURLOptionsKey.annotation]
        )) {
            return true;
        } else {
            return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
        }
    }

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        // Called when the app was launched with an activity, including Universal Links.
        // Feel free to add additional processing here, but if you want the App API to support
        // tracking app url opens, make sure to keep this call
        return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)

        let statusBarRect = UIApplication.shared.statusBarFrame
        guard let touchPoint = event?.allTouches?.first?.location(in: self.window) else { return }

        if statusBarRect.contains(touchPoint) {
            NotificationCenter.default.post(name: .capacitorStatusBarTapped, object: nil)
        }
    }

}

Could you advice please?

Fails on android after updating to Capacitor 5

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.getcapacitor.JSObject.getString(java.lang.String)' on a null object reference

Looks like in the buildIOSParamaters function, the val iosParameters = call.getObject("iosParameters") returns null so all the other attempts to check if attributes throw null reference errors, eg. if (iosParameters.getString("bundleId") != null) {

I tried just returning from the function if it is null, then I got no error but also nothing happened in my app

Deferred deeplink information

In my capacitor app I am already using Capacitor deeplinks via Capacitor Deeplink.

I already have website, android and iOS working.
My Deeplink: https://www.example.com/user/123 etc
When user clicks on this link it opens my app.

Now, if user don't have my app installed i want them to go to appstore or playstore and install app then redirect them to clicked link after installation.

Now my question is how can i setup firebase dynamic deeplinks?

improve a little the readme

this plugin works fine but to make it working I had to study and debug because I've used the class CapacitorFirebaseDynamicLinks instead of FirebaseDynamicLinks with the result that events aren't registered and triggered. I think a couple of lines with an example like this can be enough:

import {FirebaseDynamicLinks} from '@pantrist/capacitor-firebase-dynamic-links'; 
// ...
FirebaseDynamicLinks.addListener('deepLinkOpen', (data: { url: string }) => {
    // ....
);

do you need a PR for this?

Capacitor4 Docs Conflics with README

In the README plugin is registered after the registerPlugin function
But Capacitor 4 wants plugins to make it before the registerPlugin

https://capacitorjs.com/docs/updating/4-0#change-registerplugin-order

Should we still register this plugin or can we remove it?

Android

In file android/app/src/main/java/**/**/MainActivity.java, add the plugin to the initialization list:

import com.pantrist.firebase.dynamiclinks.CapacitorFirebaseDynamicLinks;

public class MainActivity extends BridgeActivity {
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      ...
      registerPlugin(CapacitorFirebaseDynamicLinks.class);
   }
}

[iOS] Deeplink info not surviving after going through Apple App Store

We have encountered a problem that the deeplink is not surviving when going through the App Store.

When we set up a dynamic link which includes a deep link with specific path, users on iOS who downloaded the app do not get directed to the correct path defined on the deeplink.
The issue only occurs on iOS for the case that the user downloads the app.

How to reproduce:

  • The user uses iOS and has the app not installed
  • User clicks on a dynamic link (both custom domain and 'page.link' domains have been used)
  • User downloads the app, clicks on open
  • User completes the onboarding
  • Then the callback of the plugin should trigger and pass the "decoded" deeplink defined on Firebase. Instead, the deepLinkOpen event is triggered but the deeplink url is missing.

We suspect that the information about the deeplink is lost somewhere in the Apple App Store. For Android this works perfectly and has no issues.

Has anybody encountered similar issues? Anyone has any suggestions how to solve this?

Thanks!

iOS the creation of Dynamic Short link is not working

The method name createDynamicShortLink is working on Android for creating shortLinks for FirebaseDynamicLink but in iOS it is always giving error

{"message":"Unable to create link","errorMessage":" "}

I have tested in iOS 15.5
Iphone 6s.

Please look into the issue

Support Capacitor 5.0

IS there any plans to support Capacitor 5? The change list looks minimal so it should be a quick fix.

Questions about being confident of recognizing the initial user

Hi @NLueg ,

I already asked my question on another repo. You all try to target the same need, but I'm missing some information and I hope to get it somewhere :) .

If you could take a look at sencrop/capacitor-firebase-dynamic-links#6 (comment) and tell me what you think, it would be great!

Thank you,

For record here is the message:

I'm interested by the "MatchType" variable in iOS to leverage the Firebase score if they are confident this is a user coming from the initial link or not:
https://firebase.google.com/docs/reference/swift/firebasedynamiclinks/api/reference/Enums/DLMatchType

From what I understand it would allow me to know for iOS if the user clicking the dynamic link before installation is the same than after (can be useful for referral system and so on...). Do you plan to support this?

I guess on Android this score does not exist because Firebase is able to pass a parameter "referrer-id" to the store, that will be pass to the app at the end, so there is no doubt of the "uniqueness" (user at click, user at install). (ref: https://stackoverflow.com/questions/58790604/matchtype-in-android-firebase-dynamic-link-sdk)

Aside this, I try to figure out a case where Firebase does not document that much:
I plan to integrate your plugin in my PWA app, and when on a browser on a mobile, dynamic link will work perfectly, except that when I'm in a desktop browser, the redirection is targeting the link, not the store (I thought at first Firebase would set the fallback automatically but it does not make sense if online version). In my case, I have a Smart App Banner to encourage the user installing the native app, so when on desktop browser I let the choice on it between Android and iOS installation, when the choice is made by the user I create the dynamic link with ofl parameter as the right store link (iOS/Android) so the user are redirected to it. At the end the user will know how to install the native app (moreover Google facilitates it from the browser since we see already linked devices), but I'm not sure after installation the user will be recognized based on IP... have you tried something similar? Or an advice?

Question on how to config the app domain like cordova plugin

Hi,

I used to work with cordova plugin dynamic linking, after successful installation the plugin will add configuration in package.json file like
"cordova-plugin-firebase-dynamiclinks": { "APP_DOMAIN_NAME": "appName.page.link", "APP_DOMAIN_PATH": "/", "IOS_FIREBASE_DYNAMICLINKS_VERSION": "8.1.1,", "ANDROID_FIREBASE_DYNAMICLINKS_VERSION": "19.1.+", "IOS_FIREBASE_POD_VERSION": "8.1.1" },

Then we can setup dynamic link in firebase console with same APP_DOMAIN_NAME value then it works.
I don't know how to configure the domain for the capacitor plugin version?

Thanks,
Phile

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.