0
votes

I have developed a SharePoint WebPart that I'm using as app in Teams. From this WebPart I call an external site (http://xxxx/example.html) to store some data with indexedDB.

 public async render() {
      this.domElement.innerHTML = `<iframe src="http://xxxx/example.html?token=xxxxxxxx"/>`;
 }

If I try to use this app in Teams from Chrome, Firefox... and with the desktop app all works fine but I have discovered an error when I try to use the application with the android app for Teams.

What can I do to work with the indexedDB from the android app for Teams?

This is the code of the external site (http://xxxx/example.html) that I'm invoking from the WebPart:

If I try to use the app in the Android app for Teams I have the following error:

'It is necessary for the correct functioning of the app to allow access to IndexedDB.'

In other cases: Desktop App, using navigators... works fine. From my point of view is something relative to the way that the Android App handle the indexedDB.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example</title>
</head>
<body>

<script>

  var tableName = '_test';
  var key = 'a2B2MSmQa1';
  var mydb;
  var entry = getEntry();
  var stringEntry = JSON.stringify(entry);

  function getEntry() {
    // prepare authentication info
    var token = findGetParameter('token');
    var user = getUserFromJwt(token);
    console.log('Received request to log in with token: ' + token + ' and user: ' + user);

    return [{
      "AnyeP3Hy11": btoa(user),
      "bcdW7Sibfo": "",
      "AE1RLE62l3": true,
      "Tx22M4zx51": btoa(token),
      "1l2i483Zx5": false
    }];
  }

  function getUserFromJwt(token) {
    var payload = token.split('.')[1];
    var claims = JSON.parse(atob(payload));

    return claims.email;
  }

  function saveTokenDataWebSql() {
    mydb.transaction(function (t) {
      t.executeSql('select * from ' + tableName + ' where key = ?', [key], function (transaction, data) {
        if (!data.rows.length) {
          // if authentication info doesn't already exists -> create it it
          mydb.transaction(function (t) {
            t.executeSql('insert into ' + tableName + '(key, value) values (?, ?)', [key, stringEntry], goToApp);
            console.log('Inserted entry');
          });
        } else {
          // if authentication info already exists -> replace it
          mydb.transaction(function (t) {
            t.executeSql('update ' + tableName + ' set value = ? where key = ?', [stringEntry, key], goToApp);
            console.log('Updated entry');
          });
        }
      });
    });
  }

  function saveTokenDataIndexedDB(objectStore) {
    objectStore.count(key).onsuccess = function (event) {
      var count = event.target.result;
      if (count !== 0) {
        // if authentication info already exists -> remove it
        objectStore.delete(key).onsuccess = function () {
          // save auth info after deletion
          objectStore.put(entry, key);
        };
      } else {
        // save auth info directly
        objectStore.put(entry, key);
      }

    };
  }

  var indexedDBWay = function () {
    console.log('Using indexedDB option');

    var request = indexedDB.open('__mydb', 2);
    request.onerror = function (event) {
      alert('It is necessary for the correct functioning of the app to allow access to IndexedDB.');
    };
    request.onsuccess = function (event) {
      mydb = event.target.result;

      try {
        console.log('Database opened, checking existence of table');
        var objectStore = mydb.transaction([tableName], 'readwrite')
          .objectStore(tableName);

        console.log('Table exists. Proceeding to save data');
        saveTokenDataIndexedDB(objectStore);

        console.log('All done, going to app');
        goToApp();
      } catch (e) {
        console.log(e);
      }
    };
  };

  var openDatabaseWay = function () {
    console.log('Using openDatabase option');

    mydb = openDatabase('__mydb', '1', 'desc', 1024 * 1024);

    console.log('Database opened, checking existence of table');

    mydb.transaction(function (t) {
      t.executeSql('select * from ' + tableName, [], function (transaction, data) {
        if (data.rows) {
          console.log('Table exists. Proceeding to save data');
          saveTokenDataWebSql();
        } else {
          console.error('App DB not present, go back to app');
          goToApp();
        }
      }, function (t, e) {
        console.log('Error while opening database', e);
        console.log('Creating database');
        createWebSqlDbTable(t, tableName, function () {
          openDatabaseWay();
        }, function (t, e) {
          console.log('Error while creating database. All hope is lost.', e);
          goToApp();
        })
      });
    });
  };

  function createWebSqlDbTable(t, tableName, callback, errorCallback) {
    t.executeSql(
      'CREATE TABLE IF NOT EXISTS ' + tableName +
      '(id INTEGER PRIMARY KEY, key unique, value)',
      [],
      callback,
      errorCallback
    );
  }

  console.log('Trying to save token data');
  var debug = location.search.indexOf('debug') !== -1;
  if(debug){
    debugger;
  }
  if (window.openDatabase) {
    openDatabaseWay();
  } else if (window.indexedDB) {
    indexedDBWay();
  } else {
    console.error('Cannot open database, go back to app');
    goToApp();
  }

</script>

</body>
</html>

Could somebody give me any clue?

Regards!

1
What is the error? What is the code that generates the error?Josh
@Vcima, Please share the error or error screenshot.Abhijit
Hi @Abhijit-MSFT. I have added more information about the errorvcima
@Vcima, doesn't look like Teams issue. if you run webpart independently in SharePoint and try to access it in android system - you should get the same error.Abhijit
@Abhijit-MSFT works fine with Sharepoint, from my point of view is something relative to the Teams WebView Browsevcima

1 Answers

1
votes

Android loads the app on a WebView. WebViews are not as powerful / feature rich as full blown browsers. It has to be seen if WebViews support indexDB at all.

https://caniuse.com/#search=indexDB. This says IndexDB is supported Chrome for Android 81+. You can check what chrome version shows up on the webview. This is again mobile dependent. (use chrome://inspect from laptop chrome browser while your mobile is debuggable and connected)

It could also be permissions. I am not sure though. I read this somewhere. To rule this out, can you try by manually providing storage permission to teams app to verify if it solves the issue?

If these does not help, most likely it is a WebView issue or Teams has to do something to enable indexDB, if it is supported by WebView.