GoogleChromeLabs / svgomg-twa

A sample that project Trusted Web Activities technology to wrap SVGOMG in an Android Application
Apache License 2.0
519 stars 132 forks source link

Feedback about TWA #48

Closed naveedahmed1 closed 4 years ago

naveedahmed1 commented 5 years ago

I recently migrated my app to TWA, and wanted to share some feedback.

Being primarily a web dev, I always had this believe that web apps would eventually land on App Stores, glad to see that its finally happening. Great job Google team :)

There are few things that I wanted to point out and if these could be fixed it would be awesome.

My PWA make use to Push notifications, Credential Management API and Web Share API.

Web Share API and Credential Management API works perfectly in TWA.

There are some issue with Push Notifications, although clicking a Push Notification from notifications tray, launches the App, similarly clicking Action Button on a Push Notification does open the app, but it doesn't switch to the app, we have to swipe up to close the notifications panel to see the app.

When the app is already running (in background/minimized), clicking the push notification, launches the app again, I mean shows the splash screen again and re-init the PWA. If it could reuse the already running instance of the app it would be great and would improve the user experience.

There should be a way to minimize app when the back button is pressed in app. Currently if we are on the root page and press back button it closes the app, whereas in most of the apps, this actually minimize the app and send app to background. And when we re open the app it reuses the same instance. If the same behavior could be implemented for TWA it would be great.

I have start_url:"/account/dashboard" specified in manifest.json but when I open my TWA app it launches the root page instead of starting app from url /account/dashboard.

My app also uses third party login and allow users to login using Google, Facebook or LinkedIn account. But the issue is when user clicks link of any of the provider e.g. Facebook, it takes too much time to launch new tab and present user with login screen. Can this experience be improved?

I'm also not clear about the push notifications permissions in TWA, are the push notifications enabled by default in TWA?

PEConn commented 5 years ago

Hey,

There are some issue with Push Notifications, although clicking a Push Notification from notifications tray, launches the App, similarly clicking Action Button on a Push Notification does open the app, but it doesn't switch to the app, we have to swipe up to close the notifications panel to see the app.

Do you mind sharing the Service Worker code for your push notification? (Also a video would be helpful, but not essential.)

When the app is already running (in background/minimized), clicking the push notification, launches the app again, I mean shows the splash screen again and re-init the PWA. If it could reuse the already running instance of the app it would be great and would improve the user experience.

This is a known issue, tracked at https://crbug.com/999590 .

There should be a way to minimize app when the back button is pressed in app.

This seems like a reasonable request (I'm actually surprised we haven't come across it before), I've created to https://crbug.com/1009968 track it.

I have start_url:"/account/dashboard" specified in manifest.json but when I open my TWA app it launches the root page instead of starting app from url /account/dashboard.

TWA's don't pay attention to your Web App Manifest - they care instead about your AndroidManifest (which gets populated by build.gradle). Is there any reason don't want to use that?

My app also uses third party login and allow users to login using Google, Facebook or LinkedIn account. But the issue is when user clicks link of any of the provider e.g. Facebook, it takes too much time to launch new tab and present user with login screen. Can this experience be improved?

What is happening when the user clicks, are they getting the Facebook app or just a webpage? Any more information (or videos) you provide would really help here.

I'm also not clear about the push notifications permissions in TWA, are the push notifications enabled by default in TWA?

From Chrome 75, the website for a TWA gets the notification permission enabled by default (provided the enableNotifications field in build.gradle is set to true). If the user disables notifications for the TWA in Android Settings, this propagates through to Chrome, disabling notifications for the website.

naveedahmed1 commented 5 years ago

Do you mind sharing the Service Worker code for your push notification? (Also a video would be helpful, but not essential.)

importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');

firebase.initializeApp({
  'messagingSenderId': '123465789'
});

const messaging = firebase.messaging();

self.addEventListener('notificationclick', function (event) {

  event.notification.close();

  if (event.action !== 'close') {
    var payload = event.notification;
    var url = '';
    if (payload['data'].type === 'myAction') {
      url = 'https://www.mydomain.com/account/myAction?utm_source=shortlisted-notification&utm_medium=push';
    }

    if (url) {
      event.waitUntil(self.clients.openWindow(url));
    }
  }
});

messaging.setBackgroundMessageHandler(function (payload) {
  const notificationTitle = payload['data'].title;

  let actions = [];
  if (payload['data'].type === 'myAction') {
    actions = [
      {
        action: 'apply', title: 'My Action'
      },
      {
        action: 'close', title: 'Ignore'
      }
    ];
  }

  let data = payload['data'];

  const notificationOptions = {
    body: payload['data'].body,
    icon: payload['data'].image,
    requireInteraction: true,
    data: data,
    actions: actions,
    badge : 'https://www.mydomain.com/content/images/icon_silhouette.png',
    sound: 'https://www.mydomain.com/content/images/pop_drip.wav'
  };

  return self.registration.showNotification(notificationTitle,
    notificationOptions);
});

TWA's don't pay attention to your Web App Manifest - they care instead about your AndroidManifest (which gets populated by build.gradle). Is there any reason don't want to use that?

Can we specify a TWA launch url in AndroidManifest?

If I share TWA download link, will it help?

One more thing, TWA takes to long to start , whereas installed PWA is much faster.

From Chrome 75, the website for a TWA gets the notification permission enabled by default

Any plans to offer similar experience for installed PWAs? I mean when user install a PWA what if the notifications are also enabled for it like we have in TWA?

The notification received from TWA shows URL along with the App Name, what if in case of TWA it just show the App Name to give it more app like feel?

naveedahmed1 commented 5 years ago

Should we expect any new features related to TWA in Chrome Dev Summit? If there are, I would be happy to test in my app :)

PEConn commented 5 years ago

Thanks for the ServiceWorker code - I was mostly trying to work out whether you were using openWindow or focus. Is that the code that executes when you click on the action button of the app (I don't know how web notification action buttons work).

If you open app/build.gradle (not the top level build.gradle) you'll see an object called twaManifest. In here you can change the launchUrl to be what you like. This value is then substituted into the AndroidManifest.xml.

If you send me a link to your APK I'll try to have a look at the start time issue. What phone are you trying this on?

I'm not sure if that's on our roadmap for our install PWAs plan, I'll ask around.

You can customize the notification that is shown, but that is slightly more involved (involves Java). You can find more information in the comments here, but be wary that that code is likely to undergo some changes soon.

The biggest thing we're working on at the moment is getting this code into AndroidX (ensuring it meets the standards for an Android API and such). There are some smaller features coming out (eg, support for web share), but until the AndroidX stuff is done the APIs will be very liable to change.

naveedahmed1 commented 5 years ago

The below code is executed when notification or notification button is clicked. event.action has the information about which action button was clicked in notification.

self.addEventListener('notificationclick', function (event) {

  event.notification.close();

  if (event.action !== 'close') {
    var payload = event.notification;
    var url = '';
    if (payload['data'].type === 'myAction') {
      url = 'https://www.mydomain.com/account/myAction?utm_source=shortlisted-notification&utm_medium=push';
    }

    if (url) {
      event.waitUntil(self.clients.openWindow(url));
    }
  }
});

I just emailed you the link to TWA. please also try clicking the social logins button (Facebook, Google, Linkedin) you will see that it also throws error, probably because the TWA is re-initialized, when the user authorize app and is redirected back to the TWA and since session doesn't match it throws 404 not found error.

It would be great if the notifications are enabled in installed PWA (when user Add to Home Screen) by default as these are enabled in TWA.

rockeynebhwani commented 5 years ago

@naveedahmed1 / @PEConn - Please see this bug I raised with respect to 3rd party re-direction. It's not only issue with social login buttons. We are also facing this for Payment re-direction scenarios like Paypal - https://bugs.chromium.org/p/chromium/issues/detail?id=1010449

@PEConn - This is deal breaker for sites which use Paypal.

PEConn commented 5 years ago

naveedahmed1, with regard to the log in through Google (I've not tried Facebook or LinkedIn), I'm unable to do so successfully on your desktop site either.

  1. Go to mustakbil.com.
  2. Click Login at the top right.
  3. Click Google.
  4. You'll be taken to the Google OAuth page, choose an account.
  5. You get the "Sorry Page Not Found!" page (URL = https://www.mustakbil.com/ws/account/externallogincallback#).
rockeynebhwani commented 5 years ago

@PEConn - I am happy to share our APK for you to try out paypal flow.. If you let me know your email address, I can send our APK and you can see PayPal flow working on our live site.

andreban commented 5 years ago

@rockeynebhwani I'd be happy to take a look at it. It's probably better to share through Google Drive or Dropbox though, as Gmail is likely to remove attached APKs.

rockeynebhwani commented 5 years ago

Thanks @andreban . I had your email address from Bojan. I have invited you to a oneDrive folder which has APK and video recording of the issue. Happy for you to place live order on the site for a small value item (search for 'unicorn tealight' - https://direct.asda.com/george/home/candles-home-fragrance/unicorn-shaped-tealight-holders-set-of-2/BUN467,default,pd.html) and give me order number and I will get it refunded.

andreban commented 5 years ago

@rockeynebhwani Thank you - I tried it out and reproduced the issue. My wild guess is that it has something to do with Digital Asset Links capturing the link and re-creating the tab when a redirect happens, instead of simply navigating. Need to confirm that though.

naveedahmed1 commented 5 years ago

@PEConn Thanks for looking into this, I am unable to reproduce it on my side. I think it happens only when the login flow breaks possibly due to the reason identified by @andreban i.e.

Digital Asset Links capturing the link and re-creating the tab when a redirect happens, instead of simply navigating.

And on redirect you can see that it shows splash screen again, therefore, it surely is recreating the tab.

@rockeynebhwani yes you are right it affects every application that somehow integrates third-party services that requires redirect to the external site and then back to the app.

rockeynebhwani commented 4 years ago

@naveedahmed1 - @andreban and I have been exchanging emails and he confirmed that he was able to re-produce the PayPal issue on a sample app.

alastaircoote commented 4 years ago

similarly clicking Action Button on a Push Notification does open the app, but it doesn't switch to the app, we have to swipe up to close the notifications panel to see the app.

Just chiming in on this particular issue: this happens on the web as well. There's an existing Chromium bug for it, closed as WONTFIX since it is an underlying Android issue rather than a Chromium one:

https://bugs.chromium.org/p/chromium/issues/detail?id=626366

Though I'd be curious to know if the decision might be different in the context of this library rather than the browser as a whole.

naveedahmed1 commented 4 years ago

Well, in case of installed PWA its works perfectly, then why this couldn't be fixed for TWAs?

naveedahmed1 commented 4 years ago

Update & Feedback:

I have updated my TWA with latest version of svgomg-twa, below is my feedback:

There are some issue with Push Notifications, although clicking a Push Notification from notifications tray, launches the App, similarly clicking Action Button on a Push Notification does open the app, but it doesn't switch to the app, we have to swipe up to close the notifications panel to see the app.

Clicking Push Notification or action button no longer opens the app rather it opens the link in the web browser.

There should be a way to minimize app when the back button is pressed in app. Currently if we are on the root page and press back button it closes the app, whereas in most of the apps, this actually minimize the app and send app to background. And when we re open the app it reuses the same instance. If the same behavior could be implemented for TWA it would be great.

Though it seems that clicking back button now minimizes the app, and its still running in background. But when I click the app icon again, it shows the splash screen instead of instantly switching to the app.

One more thing which I noticed, when are on the root page and press back button to minimize app, it briefly displays the toolbar with , X (close) button in title bar, similar to what we see with custom tab with unverified origin.

I have start_url:"/account/dashboard" specified in manifest.json but when I open my TWA app it launches the root page instead of starting app from url /account/dashboard.

Though it still doesn't honor the start_url specified in manifest.json, but launchUrl setting in build.gradle does work perfectly.

My app also uses third party login and allow users to login using Google, Facebook or LinkedIn account. But the issue is when user clicks link of any of the provider e.g. Facebook, it takes too much time to launch new tab and present user with login screen. Can this experience be improved?

This has been finally fixed, and we can now deploy our TWA to the app store.

I hope these minor issues could be fixed soon, so that we have TWA experience could be improved further.

Looking forward for a positive response.

andreban commented 4 years ago

@naveedahmed1

I have updated my TWA with latest version of svgomg-twa, below is my feedback:

We're moving to llama-pack instead of svgomg-twa. I'd recommend using that when generating / updating TWA projects. This repo will still be around, and we'll update the content via llama-pack.

Even if you intent to bootstrap the project and then customise in Android Studio, the template in llama-pack will be the most up-to-date.

Clicking Push Notification or action button no longer opens the app rather it opens the link in the web browser.

Could share the content of your build.gradle and AndroidManifest.xml? As @PEConn mentioned previously, a video would greatly help us understand what is happening.

Though it still doesn't honor the start_url specified in manifest.json, but launchUrl setting in build.gradle does work perfectly.

This is working as intended. Developers may not want to have the same start url for the PWA and the TWA. The canonical example is developers who want to append different query-strings to those URLs for analytics purposes.

llama-pack generates this value from the start_url in the Web Manifest, but allows the user to customise it.

This has been finally fixed, and we can now deploy our TWA to the app store.

I'm unsure if we changed anything on our side that would improve this. Happy to hear its fixed though.

naveedahmed1 commented 4 years ago

Thank you so much @andreban

We're moving to llama-pack instead of svgomg-twa. I'd recommend using that when generating / updating TWA projects. This repo will still be around, and we'll update the content via llama-pack.

This sounds great! I just tried it but its throwing error at this step:

? URL to an image that is at least 512x512px to be used when generating maskable icons 57
>> TypeError: uri.match is not a function  

I am entering https://www.mustakbil.com/content/images/icon-512x512.png as the url.

Here's my build.gradle file:

/*
 * Copyright 2019 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import groovy.xml.MarkupBuilder;

apply plugin: 'com.android.application'

// Apply the Performance Monitoring plugin
apply plugin: 'com.google.firebase.firebase-perf'

def twaManifest = [
    applicationId: 'com.mustakbil',
    hostName: 'www.mustakbil.com', // The domain being opened in the TWA.
    launchUrl: '/account/jobseeker', // The start path for the TWA. Must be relative to the domain.
    name: 'Mustakbil', // The name shown on the Android Launcher.
    themeColor: '#3F51B5', // The color used for the status bar.
    navigationColor: '#303F9F', // The color used for the navigation bar.
    backgroundColor: '#f8f8f9', // The color used for the splash screen background.
    enableNotifications: true, // Set to true to enable notification delegation.
    // Add shortcuts for your app here. Every shortcut must include the following fields:
    // - name: String that will show up in the shortcut.
    // - short_name: Shorter string used if |name| is too long.
    // - url: Absolute path of the URL to launch the app with (e.g '/create').
    // - icon: Name of the resource in the drawable folder to use as an icon.
    shortcuts: [
        // Insert shortcuts here, for example:
        // [name: 'Open SVG', short_name: 'Open', url: '/open', icon: 'splash']
    ],
    // The duration of fade out animation in milliseconds to be played when removing splash screen.
    splashScreenFadeOutDuration: 300
]

android {
    compileSdkVersion 29
    defaultConfig {
        applicationId twaManifest.applicationId
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 3
        versionName "2.0.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        // The name for the application on the Android Launcher
        resValue "string", "appName", twaManifest.name

        // The URL that will be used when launching the TWA from the Android Launcher
        def launchUrl = "https://" + twaManifest.hostName + twaManifest.launchUrl
        resValue "string", "launchUrl", launchUrl

        // The URL that will be opened as a Desktop PWA when the TWA is installed and
        // run on ChromeOS. This will probably give a better user experience for non-mobile
        // devices, but will not include any native Android interaction.
        resValue "string", "crosLaunchUrl", launchUrl

        // The hostname is used when building the intent-filter, so the TWA is able to
        // handle Intents to open https://svgomg.firebaseapp.com.
        resValue "string", "hostName", twaManifest.hostName

        // This variable below expresses the relationship between the app and the site,
        // as documented in the TWA documentation at
        // https://developers.google.com/web/updates/2017/10/using-twa#set_up_digital_asset_links_in_an_android_app
        // and is injected into the AndroidManifest.xml
        resValue "string", "assetStatements", """
            [{
                "relation": ["delegate_permission/common.handle_all_urls"],
                "target": {
                    "namespace": "web",
                    "site": "https://$twaManifest.hostName"
                }
            }]"""

        // This attribute sets the status bar color for the TWA. It can be either set here or in
        // `res/values/colors.xml`. Setting in both places is an error and the app will not
        // compile. If not set, the status bar color defaults to #FFFFFF - white.
        resValue "color", "colorPrimary", twaManifest.themeColor

        // This attribute sets the navigation bar color for the TWA. It can be either set here or in
        // `res/values/colors.xml`. Setting in both places is an error and the app will not
        // compile. If not set, the navigation bar color defaults to #FFFFFF - white.
        resValue "color", "navigationColor", twaManifest.navigationColor

        // Sets the color for the background used for the splash screen when launching the
        // Trusted Web Activity.
        resValue "color", "backgroundColor", twaManifest.backgroundColor

        // Defines a provider authority fot the Splash Screen
        resValue "string", "providerAuthority", twaManifest.applicationId + '.fileprovider'

        // The enableNotification resource is used to enable or disable the
        // TrustedWebActivityService, by changing the android:enabled and android:exported
        // attributes
        resValue "bool", "enableNotification", twaManifest.enableNotifications.toString()

        twaManifest.shortcuts.eachWithIndex { shortcut, index ->
            resValue "string", "shortcut_name_$index", "$shortcut.name"
            resValue "string", "shortcut_short_name_$index", "$shortcut.short_name"
        }

        // The splashScreenFadeOutDuration resource is used to set the duration of fade out animation in milliseconds
        // to be played when removing splash screen. The default is 0 (no animation).
        resValue "integer", "splashScreenFadeOutDuration", twaManifest.splashScreenFadeOutDuration.toString()
    }
    buildTypes {
        release {
            minifyEnabled true
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

task generateShorcutsFile {
    assert twaManifest.shortcuts.size() < 5, "You can have at most 4 shortcuts."
    twaManifest.shortcuts.eachWithIndex { s, i ->
        assert s.name != null, 'Missing `name` in shortcut #' + i
        assert s.short_name != null, 'Missing `short_name` in shortcut #' + i
        assert s.url != null, 'Missing `icon` in shortcut #' + i
        assert s.icon != null, 'Missing `url` in shortcut #' + i
    }

    def shortcutsFile = new File("$projectDir/src/main/res/xml", "shortcuts.xml")

    def xmlWriter = new StringWriter()
    def xmlMarkup = new MarkupBuilder(new IndentPrinter(xmlWriter, "    ", true))

    xmlMarkup
        .'shortcuts'('xmlns:android': 'http://schemas.android.com/apk/res/android') {
            twaManifest.shortcuts.eachWithIndex { s, i ->
                'shortcut'(
                        'android:shortcutId': 'shortcut' + i,
                        'android:enabled': 'true',
                        'android:icon': '@drawable/' + s.icon,
                        'android:shortcutShortLabel': '@string/shortcut_short_name_' + i,
                        'android:shortcutLongLabel': '@string/shortcut_name_' + i) {
                    'intent'(
                            'android:action': 'android.intent.action.MAIN',
                            'android:targetPackage': twaManifest.applicationId,
                            'android:targetClass': 'android.support.customtabs.trusted.LauncherActivity',
                            'android:data': 'https://' + twaManifest.hostName + s.url)
                    'categories'('android:name': 'android.intent.category.LAUNCHER')
                }
            }
        }
    shortcutsFile.text = xmlWriter.toString() + '\n'
}

preBuild.dependsOn(generateShorcutsFile)

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.google.androidbrowserhelper:androidbrowserhelper:1.1.0'

    // Add the dependency for the Performance Monitoring library
    implementation 'com.google.firebase:firebase-perf:19.0.5'

}

Here's my AndroidManifest.xml

<!--
    Copyright 2019 Google Inc. All Rights Reserved.

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<!-- The "package" attribute is rewritten by the Gradle build with the value of applicationId.
     It is still required here, as it is used to derive paths, for instance when referring
     to an Activity by ".MyActivity" instead of the full name. If more Activities are added to the
     application, the package attribute will need to reflect the correct path in order to use
     the abbreviated format. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.placeholder">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/appName"
        android:supportsRtl="true"
        android:theme="@style/Theme.LauncherActivity">

        <meta-data
            android:name="asset_statements"
            android:resource="@string/assetStatements" />
        <meta-data
            android:name="cros_web_alternative"
            android:value="@string/crosLaunchUrl" />

        <activity android:name="com.google.androidbrowserhelper.trusted.LauncherActivity"
            android:label="@string/appName">
            <meta-data android:name="android.support.customtabs.trusted.DEFAULT_URL"
                android:value="@string/launchUrl" />

            <meta-data
                android:name="android.support.customtabs.trusted.STATUS_BAR_COLOR"
                android:resource="@color/colorPrimary" />

            <meta-data
                android:name="android.support.customtabs.trusted.NAVIGATION_BAR_COLOR"
                android:resource="@color/navigationColor" />

            <meta-data android:name="android.support.customtabs.trusted.SPLASH_IMAGE_DRAWABLE"
                android:resource="@drawable/splash"/>

            <meta-data android:name="android.support.customtabs.trusted.SPLASH_SCREEN_BACKGROUND_COLOR"
                android:resource="@color/backgroundColor"/>

            <meta-data android:name="android.support.customtabs.trusted.SPLASH_SCREEN_FADE_OUT_DURATION"
                android:value="@integer/splashScreenFadeOutDuration"/>

            <meta-data android:name="android.support.customtabs.trusted.FILE_PROVIDER_AUTHORITY"
                android:value="@string/providerAuthority"/>

            <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE"/>
                <data android:scheme="https"
                    android:host="@string/hostName"/>
            </intent-filter>

        </activity>

        <activity android:name="com.google.androidbrowserhelper.trusted.FocusActivity" />

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="@string/providerAuthority"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>

        <service
             android:name="com.google.androidbrowserhelper.trusted.DelegationService"
             android:enabled="@bool/enableNotification"
             android:exported="@bool/enableNotification">

             <intent-filter>
                 <action android:name="android.support.customtabs.trusted.TRUSTED_WEB_ACTIVITY_SERVICE"/>
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </service>

    </application>
</manifest>
andreban commented 4 years ago

re: llama-pack, I think you've hit this bug: https://github.com/GoogleChromeLabs/llama-pack/issues/100 I'm on it.

naveedahmed1 commented 4 years ago

Thanks for the update @andreban . We have deployed our TWA to Play Store here's the link if you to check https://play.google.com/store/apps/details?id=com.mustakbil

andreban commented 4 years ago

Closing the issue, as the the problem has been fixed in llama-pack and other issues are being tracked elsewhere.