IndexedDB 不适用于 Microsoft Teams 的 Android 应用程序

Posted

技术标签:

【中文标题】IndexedDB 不适用于 Microsoft Teams 的 Android 应用程序【英文标题】:IndexedDB doesn't work with Android App for Microsoft Teams 【发布时间】:2020-08-20 01:09:26 【问题描述】:

我开发了一个 SharePoint WebPart,我在 Teams 中用作应用程序。在这个 WebPart 中,我调用了一个外部站点 (http://xxxx/example.html) 来使用 indexedDB 存储一些数据。

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

如果我尝试通过 Chrome、Firefox... 在 Teams 中使用此应用程序并使用桌面应用程序一切正常,但当我尝试将应用程序与适用于 Teams 的 android 应用程序一起使用时,我发现了一个错误。

我可以如何从适用于 Teams 的 Android 应用程序中使用 indexedDB?

这是我从 WebPart 调用的外部站点 (http://xxxx/example.html) 的代码:

如果我尝试在适用于 Teams 的 Android 应用中使用该应用,则会出现以下错误:

'应用程序的正常运行必须允许访问 IndexedDB。'

在其他情况下:桌面应用程序,使用导航器...工作正常。在我看来,这与 Android 应用处理 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>

谁能给我点线索?

问候!

【问题讨论】:

错误是什么?产生错误的代码是什么? @Vcima,请分享错误或错误截图。 嗨@Abhijit-MSFT。我添加了有关错误的更多信息 @Vcima,看起来不像 Teams 问题。如果您在 SharePoint 中独立运行 webpart 并尝试在 android 系统中访问它 - 您应该会收到相同的错误。 @Abhijit-MSFT 与 Sharepoint 配合得很好,从我的角度来看,这与 Teams WebView Browse 相关 【参考方案1】:

Android 在 WebView 上加载应用。 WebView 不如成熟的浏览器强大/功能丰富。 WebViews 是否支持 indexDB 还得看。

https://caniuse.com/#search=indexDB。这表示 IndexDB 支持 Chrome for Android 81+。您可以检查 webview 上显示的 chrome 版本。这又取决于移动设备。 (当您的手机可调试和连接时,使用笔记本电脑 chrome 浏览器中的 chrome://inspect)

也可以是权限。不过我不确定。我在某处读过这个。要排除这种情况,您是否可以尝试通过手动向团队应用提供存储权限来验证它是否解决了问题?

如果这些没有帮助,很可能是 WebView 问题,或者如果 WebView 支持,Teams 必须做一些事情来启用 indexDB。

【讨论】:

以上是关于IndexedDB 不适用于 Microsoft Teams 的 Android 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Azure B2C 自定义策略 REST API CALL 不适用于 Microsoft 帐户

Have/Where 子句不适用于使用 Microsoft SQL 的 Haversine 公式

具有 Azure AD 身份验证的 Azure 函数 - 允许的令牌受众不适用于 Microsoft Graph

Prepared Statement 中的绑定不适用于 Microsoft SQL Server JDBC 驱动程序 sqljdbc4.jar

STWithin 不适用于地理

UWP IsNullOrEmptyStateTrigger 不适用于 ListView