{"id":318,"date":"2018-08-06T16:42:13","date_gmt":"2018-08-06T16:42:13","guid":{"rendered":"https:\/\/blog.mozilla.org\/webrtc\/?p=318"},"modified":"2019-03-11T18:59:52","modified_gmt":"2019-03-11T18:59:52","slug":"getstats-isremote-66","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/","title":{"rendered":"isRemote in getStats() will disappear in Firefox 66"},"content":{"rendered":"<p>Are you using <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/RTCRtpSender\/getStats\"><code>getStats()<\/code><\/a> for remote statistics in Firefox? Look for this warning today in Firefox Nightly (63, not 66):<\/p>\n<p><span style=\"font-size: large; background-color: #ffb;\">\u26a0 Detected soon-to-break getStats() use! stat.isRemote goes away in Firefox 66, but won&#8217;t warn there!<br \/>\n<\/span><\/p>\n<p><strong>TL;DR:<\/strong> If you see this warning in web console, read on to act now. Firefox 66 will move remote stats to <code>\"remote-outbound-rtp\"<\/code> and <code>\"remote-inbound-rtp\"<\/code>, and <code>isRemote<\/code> will disappear, to comply with a change to the <a href=\"https:\/\/w3c.github.io\/webrtc-stats\/#dom-rtcstatstype-remote-inbound-rtp\">spec<\/a>.<\/p>\n<p>Firefox 63-65 will warn about this, but for technical reasons Firefox 66 will not be able to. This is because once the stats move in 66, there&#8217;s really no way to detect that you intended to look for remote stats the old way.<\/p>\n<p><em><strong>Update:<\/strong> The original article said Firefox 55. We&#8217;ve pushed it back to Firefox 66, giving you a little more time!<\/em><\/p>\n<p><!--more--><\/p>\n<p>Here&#8217;s a <a href=\"https:\/\/jsfiddle.net\/jib1\/5dma2p0w\/show\">an example of bad isRemote usage<\/a> that triggers this warning in Firefox Nightly (<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Tools\/Web_Console\/Opening_the_Web_Console\">open the web console<\/a> to see the warning).<\/p>\n<p>What is one to do? Prepare today! There&#8217;s already a <em>safe, spec-supported way<\/em> to access remote stats in Firefox that won&#8217;t break in Firefox 66: Use <code>remoteId<\/code> to <em>cross-reference<\/em> remote stats from local stats:<\/p>\n<h2>Use remoteId safely today<\/h2>\n<p>Access remote stats the way we&#8217;ve demonstrated in <a href=\"https:\/\/blog.mozilla.org\/webrtc\/fiddle-week-spec-compliant-getstats\/\">two<\/a> blog <a href=\"https:\/\/blog.mozilla.org\/webrtc\/fiddle-of-the-week-await\/\">posts<\/a> last year, using <code>remoteId<\/code>:<\/p>\n<pre class=\"javascript\">      const stats = await pc.getStats();\r\n      for (const stat of stats.values()) {\r\n        if (stat.isRemote) continue;\r\n        switch (stat.type) {\r\n          case <span style=\"color: #993300;\">\"outbound-rtp\"<\/span>: {\r\n            console.log(<span style=\"color: #993300;\">\"Sent \"<\/span> + stat.bytesSent);\r\n            const remote = stats.get(stat.remoteId); <span style=\"color: #339966;\">\/\/ &lt;-- Like this!<\/span>\r\n            if (remote) console.log(<span style=\"color: #993300;\">\"Other side \"<\/span> + remote.bytesReceived);\r\n            break;\r\n          }\r\n          case <span style=\"color: #993300;\">\"inbound-rtp\"<\/span>: {\r\n            console.log(<span style=\"color: #993300;\">\"Received \"<\/span> + stat.bytesReceived);\r\n            const remote = stats.get(stat.remoteId); <span style=\"color: #339966;\">\/\/ &lt;-- Like this!<\/span>\r\n            if (remote) console.log(<span style=\"color: #993300;\">\"Other side \"<\/span> + remote.bytesSent);\r\n            break;\r\n          }\r\n       }\r\n<\/pre>\n<p>This code enumerates local stats, and finds the corresponding remote stat at the same time, using the <code>remoteId<\/code> cross-reference.This is just as fast as other ways of obtaining this information, as it merely cross-references into the same already-returned <code>RTCStatsReport<\/code> object.<\/p>\n<p>Organizationally, this keeps related data together, and this approach will continue to work today, tomorrow in Firefox 66, and beyond. It should also work in Chrome once it supports remote stats in its spec API (it doesn&#8217;t today).<\/p>\n<h3>But&#8230;<\/h3>\n<p>Look carefully, and you&#8217;ll see we&#8217;re still using <code>isRemote<\/code> above in one place! Specifically:<\/p>\n<pre class=\"tCont active hljs javascript\"><span style=\"color: #333300;\">      <span class=\"hljs-keyword\">if (stat.isRemote) continue;<\/span>\r\n<\/span><\/pre>\n<p>This is not a mistake. This is needed for compatibility, or we&#8217;d mistake remote stats for local stats in today&#8217;s browsers, where they&#8217;re listed under the same type. This will continue to work in Firefox 66 where <code>isRemote<\/code> will be <code>undefined<\/code>, because that works out to the same as <code>false<\/code> in that <code>if<\/code>-statement.<\/p>\n<p>The warnings in Nightly are clever enough not to trip over this use. Instead, they trigger on any access of actual remote statistics, if it hasn&#8217;t seen use of <code>.get(remoteId)<\/code> first.<\/p>\n<h2>Don&#8217;t be like this:<\/h2>\n<p>The other way to read remote stats today is to check <code>isRemote<\/code> for true. This <em><strong>will break<\/strong><\/em> in Firefox 66:<\/p>\n<pre class=\"javascript\">      const stats = await pc.getStats();\r\n      for (const stat of stats.values()) {\r\n        switch (stat.type) {\r\n          case <span style=\"color: #993300;\">\"outbound-rtp\"<\/span>: {\r\n            if (stat.isRemote) {                           <span style=\"color: #ff0000;\">\/\/ always undefined!<\/span>\r\n              console.log(<span style=\"color: #993300;\">\"Other side \"<\/span> + stat.bytesSent); <span style=\"color: #ff0000;\">\/\/ never runs!<\/span>\r\n            } else {\r\n              console.log(<span style=\"color: #993300;\">\"Sent \"<\/span> + stat.bytesSent);       <span style=\"color: #ff0000;\">\/\/ wrong!<\/span>\r\n            }\r\n            break;\r\n          }\r\n          case <span style=\"color: #993300;\">\"inbound-rtp\"<\/span>: {\r\n            if (stat.isRemote) {                               <span style=\"color: #ff0000;\">\/\/ always undefined!<\/span>\r\n              console.log(<span style=\"color: #993300;\">\"Other side \"<\/span> + stat.bytesReceived); <span style=\"color: #ff0000;\">\/\/ will never run!<\/span>\r\n            } else {\r\n              console.log(<span style=\"color: #993300;\">\"Received \"<\/span> + stat.bytesReceived);   <span style=\"color: #ff0000;\">\/\/ wrong!<\/span>\r\n            }\r\n            break;\r\n          }\r\n       }\r\n<\/pre>\n<h2>In the future:<\/h2>\n<p>For completeness, we should mention that once Firefox 66 is out, you could also write the following, <em>but it won&#8217;t work in older versions,<\/em> obviously, because <code>\"remote-inbound-rtp\"<\/code> and <code>\"remote-outbound-rtp\"<\/code> won&#8217;t exist in those browsers:<\/p>\n<pre class=\"javascript\">      const stats = await pc.getStats();\r\n      for (const stat of stats.values()) {\r\n        switch (stat.type) {\r\n          case <span style=\"color: #993300;\">\"outbound-rtp\"<\/span>: {\r\n            console.log(<span style=\"color: #993300;\">\"Sent \"<\/span> + stat.bytesSent);\r\n            break;\r\n          }\r\n          case <span style=\"color: #993300;\">\"remote-inbound-rtp\"<\/span>: {\r\n            console.log(<span style=\"color: #993300;\">\"Other side \"<\/span> + stat.bytesReceived);\r\n            break;\r\n          }\r\n          case <span style=\"color: #993300;\">\"inbound-rtp\"<\/span>: {\r\n            console.log(<span style=\"color: #993300;\">\"Received \"<\/span> + stat.bytesReceived);\r\n            break;\r\n          }\r\n          case <span style=\"color: #993300;\">\"remote-outbound-rtp\"<\/span>: {\r\n            console.log(<span style=\"color: #993300;\">\"Other side \"<\/span> + stat.bytesSent);\r\n            break;\r\n          }\r\n       }\r\n<\/pre>\n<p>In addition to not working in older browsers, this approach has other downsides: According to the spec, stats may appear in any order, which means this example might print the log statements in any order, and not grouped together logically. For these two reasons, we recommend you stick with the <code>remoteId<\/code> example. In the future, should you at some point no longer care about older versions, you can simply drop the following line from it:<\/p>\n<pre class=\"tCont active hljs javascript\">      <span class=\"hljs-keyword\">if (stat.isRemote) continue;<\/span>\r\n<\/pre>\n<h2>Working Good Example<\/h2>\n<p>Here&#8217;s the <code>remoteId<\/code> approach again in a working example. Hit the &#8220;Result&#8221; tab to see it in action:<iframe loading=\"lazy\" src=\"https:\/\/jsfiddle.net\/jib1\/qs830j4j\/embedded\/js,result,html\/\" allow=\"camera;microphone\" width=\"100%\" height=\"760px\" frameborder=\"0\"><\/iframe><\/p>\n<p>If your stats code looks substantially different from what&#8217;s shown here, we highly recommend these previous blog posts on <a href=\"https:\/\/blog.mozilla.org\/webrtc\/fiddle-week-spec-compliant-getstats\/\">aligning with the spec on getStats()<\/a>, and <a href=\"https:\/\/blog.mozilla.org\/webrtc\/fiddle-of-the-week-await\/\">using await with WebRTC<\/a>.<\/p>\n<p>Remember,<\/p>\n<h3><code>remoteId<\/code> good \ud83d\udc4d, <code>isRemote<\/code> bad \ud83d\udc4e<\/h3>\n<p>Happy stats gathering!<\/p>\n<p>&nbsp;<\/p>\n<h4>PS: RTCIceCandidateStats<\/h4>\n<p>There&#8217;s also an <code>isRemote<\/code> member in <code>RTCIceCandidateStats<\/code>. It remains unaffected by all this.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"Are you using getStats() for remote statistics in Firefox? Look for this warning today in Firefox Nightly (63, not 66): \u26a0 Detected soon-to-break getStats() use! stat.isRemote goes away in Firefox 66, but won&#8217;t warn there! TL;DR: If you see this warning in web console, read on to act now. Firefox 66 will move remote stats [&hellip;]","protected":false},"author":1399,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"coauthors":[301098],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>isRemote in getStats() will disappear in Firefox 66 - Advancing WebRTC<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"isRemote in getStats() will disappear in Firefox 66 - Advancing WebRTC\" \/>\n<meta property=\"og:description\" content=\"Are you using getStats() for remote statistics in Firefox? Look for this warning today in Firefox Nightly (63, not 66): \u26a0 Detected soon-to-break getStats() use! stat.isRemote goes away in Firefox 66, but won&#8217;t warn there! TL;DR: If you see this warning in web console, read on to act now. Firefox 66 will move remote stats [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/\" \/>\n<meta property=\"og:site_name\" content=\"Advancing WebRTC\" \/>\n<meta property=\"article:published_time\" content=\"2018-08-06T16:42:13+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-03-11T18:59:52+00:00\" \/>\n<meta name=\"author\" content=\"Jan-Ivar Bruaroey\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jan-Ivar Bruaroey\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/\",\"name\":\"isRemote in getStats() will disappear in Firefox 66 - Advancing WebRTC\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#website\"},\"datePublished\":\"2018-08-06T16:42:13+00:00\",\"dateModified\":\"2019-03-11T18:59:52+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/webrtc\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"isRemote in getStats() will disappear in Firefox 66\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/\",\"name\":\"Advancing WebRTC\",\"description\":\"Committed to moving Firefox and WebRTC forward\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/webrtc\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd\",\"name\":\"Jan-Ivar Bruaroey\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/image\/5f3d49a61b032619d0d33c4cc7c7433f\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g\",\"caption\":\"Jan-Ivar Bruaroey\"},\"url\":\"https:\/\/blog.mozilla.org\/webrtc\/author\/jbruaroeymozilla-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"isRemote in getStats() will disappear in Firefox 66 - Advancing WebRTC","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/","og_locale":"en_US","og_type":"article","og_title":"isRemote in getStats() will disappear in Firefox 66 - Advancing WebRTC","og_description":"Are you using getStats() for remote statistics in Firefox? Look for this warning today in Firefox Nightly (63, not 66): \u26a0 Detected soon-to-break getStats() use! stat.isRemote goes away in Firefox 66, but won&#8217;t warn there! TL;DR: If you see this warning in web console, read on to act now. Firefox 66 will move remote stats [&hellip;]","og_url":"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/","og_site_name":"Advancing WebRTC","article_published_time":"2018-08-06T16:42:13+00:00","article_modified_time":"2019-03-11T18:59:52+00:00","author":"Jan-Ivar Bruaroey","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jan-Ivar Bruaroey","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/","url":"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/","name":"isRemote in getStats() will disappear in Firefox 66 - Advancing WebRTC","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/#website"},"datePublished":"2018-08-06T16:42:13+00:00","dateModified":"2019-03-11T18:59:52+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/webrtc\/getstats-isremote-66\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/webrtc\/"},{"@type":"ListItem","position":2,"name":"isRemote in getStats() will disappear in Firefox 66"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/webrtc\/#website","url":"https:\/\/blog.mozilla.org\/webrtc\/","name":"Advancing WebRTC","description":"Committed to moving Firefox and WebRTC forward","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/webrtc\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/f2eb9712b8d85b70aebe1faf24e731fd","name":"Jan-Ivar Bruaroey","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/webrtc\/#\/schema\/person\/image\/5f3d49a61b032619d0d33c4cc7c7433f","url":"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16d7e05dc9f8a855a02e0796b00aad3f?s=96&d=mm&r=g","caption":"Jan-Ivar Bruaroey"},"url":"https:\/\/blog.mozilla.org\/webrtc\/author\/jbruaroeymozilla-com\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts\/318"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/users\/1399"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/comments?post=318"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/posts\/318\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/media?parent=318"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/categories?post=318"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/tags?post=318"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webrtc\/wp-json\/wp\/v2\/coauthors?post=318"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}