question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

🐛 Adding multiple native ads to a listview

See original GitHub issue

Bug report

Describe the bug Adding multiple native ads in a listview throws the error: This AdWidget is already in the Widget tree

logs
======== Exception caught by widgets library =======================================================
The following assertion was thrown building AdWidget(dirty, state: _AdWidgetState#b7d04):
This AdWidget is already in the Widget tree


If you placed this AdWidget in a list, make sure you create a new instance in the builder function with a unique ad object.
Make sure you are not using the same ad object in more than one AdWidget.

The relevant error-causing widget was: 
  AdWidget file:///C:/Users/user/AndroidStudioProjects/******/lib/stories/package/full_page.dart:664:53
When the exception was thrown, this was the stack: 
#0      _AdWidgetState.build (package:google_mobile_ads/src/ad_containers.dart:372:7)
#1      StatefulElement.build (package:flutter/src/widgets/framework.dart:4684:27)
#2      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4567:15)
#3      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4739:11)
#4      Element.rebuild (package:flutter/src/widgets/framework.dart:4261:5)
...
====================================================================================================

Steps to reproduce

Steps to reproduce the behaviour:

I instantiated the package

code sample
NativeAd _nativeAd;

final Completer<NativeAd> nativeAdCompleter = Completer<NativeAd>();

I have a function to load the ad as follows

loadAd(){
    _nativeAd = NativeAd(
      adUnitId: "ca-app-pub-3940256099942544/1044960115",
      request: AdRequest(),
      factoryId: 'adFactoryExample',
      listener: AdListener(
        onAdLoaded: (Ad ad) {
          print('$NativeAd loaded.');
          nativeAdCompleter.complete(ad as NativeAd);
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          ad.dispose();
          print('$NativeAd failedToLoad: $error');
          nativeAdCompleter.completeError(null);
        },
        onAdOpened: (Ad ad) => print('$NativeAd onAdOpened.'),
        onAdClosed: (Ad ad) => print('$NativeAd onAdClosed.'),
        onApplicationExit: (Ad ad) => print('$NativeAd onApplicationExit.'),
      ),
    );
    Future<void>.delayed(Duration(seconds: 1), () => _nativeAd?.load());
  }

I plan to show ads dynamically in a listview as follows

case 'ad':
                                  loadAd();

                                  return FutureBuilder<NativeAd>(
                                    future: nativeAdCompleter.future,
                                    builder: (BuildContext context, AsyncSnapshot<NativeAd> snapshot) {
                                      Widget child;

                                      switch (snapshot.connectionState) {
                                        case ConnectionState.none:
                                        case ConnectionState.waiting:
                                        case ConnectionState.active:
                                          child = Container();
                                          break;
                                        case ConnectionState.done:
                                          if (snapshot.hasData) {
                                            child = AdWidget(ad: _nativeAd);
                                          } else {
                                            child = Text('Error loading $NativeAd');
                                          }
                                      }

                                      return Scaffold(
                                        body: Container(
                                          width: double.infinity,
                                          height: double.infinity,
                                          margin: EdgeInsets.only(top: 100, left: 5, right: 5, bottom: 70),
                                          child: Center(child: child),
                                          color: Colors.black,
                                        ),
                                      );
                                    },
                                  );
                                  break;

Expected behaviour

I would like to add, preload and show multiple native ads/AdWidgets to a listview in a dynamic way.


Additional context

Additional context

I have a class that implements a NativeAdFactory in Android Studio as follows:

Layout XML : ad_unified.xml :

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.formats.UnifiedNativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="684dp"
        android:layout_gravity="center"
        android:background="#FFFFFF"
        android:minHeight="50dp"
        android:orientation="vertical">

        <TextView style="@style/AppTheme.AdAttribution" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="665dp"
            android:orientation="vertical"
            android:paddingTop="3dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <ImageView
                    android:id="@+id/ad_app_icon"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:adjustViewBounds="true"
                    android:paddingEnd="5dp"
                    android:paddingRight="5dp"
                    android:paddingBottom="5dp" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <TextView
                        android:id="@+id/ad_headline"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textColor="#0000FF"
                        android:textSize="16sp"
                        android:textStyle="bold" />

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content">

                        <TextView
                            android:id="@+id/ad_advertiser"
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:gravity="bottom"
                            android:textSize="14sp"
                            android:textStyle="bold" />

                        <RatingBar
                            android:id="@+id/ad_stars"
                            style="?android:attr/ratingBarStyleSmall"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:isIndicator="true"
                            android:numStars="5"
                            android:stepSize="0.5" />
                    </LinearLayout>

                </LinearLayout>
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="622dp"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/ad_body"
                    android:layout_width="match_parent"
                    android:layout_height="37dp"
                    android:textSize="12sp" />

                <com.google.android.gms.ads.formats.MediaView
                    android:id="@+id/ad_media"
                    android:layout_width="411dp"
                    android:layout_height="496dp"
                    android:layout_gravity="center_horizontal"
                    android:layout_marginTop="5dp" />

                <LinearLayout
                    android:layout_width="412dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="end"
                    android:orientation="horizontal"
                    android:paddingTop="10dp"
                    android:paddingBottom="10dp">

                    <TextView
                        android:id="@+id/ad_price"
                        android:layout_width="201dp"
                        android:layout_height="wrap_content"
                        android:paddingStart="5dp"
                        android:paddingLeft="5dp"
                        android:paddingEnd="5dp"
                        android:paddingRight="5dp"
                        android:textSize="12sp" />

                    <TextView
                        android:id="@+id/ad_store"
                        android:layout_width="209dp"
                        android:layout_height="wrap_content"
                        android:paddingStart="5dp"
                        android:paddingLeft="5dp"
                        android:paddingEnd="5dp"
                        android:paddingRight="5dp"
                        android:textSize="12sp" />

                </LinearLayout>

                <Button
                    android:id="@+id/ad_call_to_action"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:textSize="12sp" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</com.google.android.gms.ads.formats.UnifiedNativeAdView>

in the Main Activity.java file :

package com.******;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory;

public class MainActivity extends FlutterActivity {
    @Override
    public void configureFlutterEngine(FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);
        final NativeAdFactory factory = new NativeAdFactoryExample(getLayoutInflater());
        GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "adFactoryExample", factory);
    }

    @Override
    public void cleanUpFlutterEngine(FlutterEngine flutterEngine) {
        GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "adFactoryExample");
    }
}

and in the NativeAdFactoryExample.java I have

package com.*****;

import android.view.LayoutInflater;
import android.widget.TextView;

import com.google.android.gms.ads.VideoController;
import com.google.android.gms.ads.VideoOptions;
import com.google.android.gms.ads.formats.UnifiedNativeAd;
import com.google.android.gms.ads.formats.UnifiedNativeAdView;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory;

import java.util.Map;

import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RatingBar;
import com.google.android.gms.ads.formats.MediaView;
import com.google.android.gms.ads.nativead.NativeAdOptions;


class NativeAdFactoryExample implements NativeAdFactory {
    private final LayoutInflater layoutInflater;
    NativeAdFactoryExample(LayoutInflater layoutInflater) {
        this.layoutInflater = layoutInflater;
    }

    @Override
    public UnifiedNativeAdView createNativeAd(
            UnifiedNativeAd nativeAd, Map<String, Object> customOptions) {
        final UnifiedNativeAdView adView =
                (UnifiedNativeAdView) layoutInflater.inflate(R.layout.ad_unified, null);


        // Set the media view.
        adView.setMediaView((MediaView) adView.findViewById(R.id.ad_media));

        // Set other ad assets.
        adView.setHeadlineView(adView.findViewById(R.id.ad_headline));
        adView.setBodyView(adView.findViewById(R.id.ad_body));
        adView.setCallToActionView(adView.findViewById(R.id.ad_call_to_action));
        adView.setIconView(adView.findViewById(R.id.ad_app_icon));
        adView.setPriceView(adView.findViewById(R.id.ad_price));
        adView.setStarRatingView(adView.findViewById(R.id.ad_stars));
        adView.setStoreView(adView.findViewById(R.id.ad_store));
        adView.setAdvertiserView(adView.findViewById(R.id.ad_advertiser));

        // The headline and mediaContent are guaranteed to be in every UnifiedNativeAd.
        ((TextView) adView.getHeadlineView()).setText(nativeAd.getHeadline());
        adView.getMediaView().setMediaContent(nativeAd.getMediaContent());

        adView.setNativeAd(nativeAd);

        if (nativeAd.getBody() == null) {
            adView.getBodyView().setVisibility(View.INVISIBLE);
        } else {
            adView.getBodyView().setVisibility(View.VISIBLE);
            ((TextView) adView.getBodyView()).setText(nativeAd.getBody());
        }

        if (nativeAd.getCallToAction() == null) {
            adView.getCallToActionView().setVisibility(View.INVISIBLE);
        } else {
            adView.getCallToActionView().setVisibility(View.VISIBLE);
            ((Button) adView.getCallToActionView()).setText(nativeAd.getCallToAction());
        }

        if (nativeAd.getIcon() == null) {
            adView.getIconView().setVisibility(View.GONE);
        } else {
            ((ImageView) adView.getIconView()).setImageDrawable(
                    nativeAd.getIcon().getDrawable());
            adView.getIconView().setVisibility(View.VISIBLE);
        }

        if (nativeAd.getPrice() == null) {
            adView.getPriceView().setVisibility(View.INVISIBLE);
        } else {
            adView.getPriceView().setVisibility(View.VISIBLE);
            ((TextView) adView.getPriceView()).setText(nativeAd.getPrice());
        }

        if (nativeAd.getStore() == null) {
            adView.getStoreView().setVisibility(View.INVISIBLE);
        } else {
            adView.getStoreView().setVisibility(View.VISIBLE);
            ((TextView) adView.getStoreView()).setText(nativeAd.getStore());
        }

        if (nativeAd.getStarRating() == null) {
            adView.getStarRatingView().setVisibility(View.INVISIBLE);
        } else {
            ((RatingBar) adView.getStarRatingView())
                    .setRating(nativeAd.getStarRating().floatValue());
            adView.getStarRatingView().setVisibility(View.VISIBLE);
        }

        if (nativeAd.getAdvertiser() == null) {
            adView.getAdvertiserView().setVisibility(View.INVISIBLE);
        } else {
            ((TextView) adView.getAdvertiserView()).setText(nativeAd.getAdvertiser());
            adView.getAdvertiserView().setVisibility(View.VISIBLE);
        }
        adView.setNativeAd(nativeAd);

        VideoController vc = nativeAd.getVideoController();

        if (vc.hasVideoContent()) {
            VideoOptions videoOptions =
                    new VideoOptions.Builder().setStartMuted(false).setClickToExpandRequested(true).build();

            NativeAdOptions adOptions =
                    new NativeAdOptions.Builder().setVideoOptions(videoOptions).build();

            vc.play();
        }    
        
        return adView;

    }
}
---

Flutter doctor

Run flutter doctor and paste the output below:

This is my `flutter doctor summary`
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel dev, 2.1.0-12.1.pre, on Microsoft Windows [Version 10.0.19042.631], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[√] Android Studio (version 4.1.0)
[√] VS Code (version 1.54.2)
[√] Connected device (4 available)

• No issues found!

Flutter dependencies

Run flutter pub deps -- --style=compact and paste the output below:

`flutter pub deps -- --style=compact` summary
Dart SDK 2.13.0-116.0.dev
Flutter SDK 2.1.0-12.1.pre
****** 1.0.0+1

dependencies:
- auto_size_text_field 0.1.7 [flutter]
- bubbled_navigation_bar 0.0.4 [flutter]
- cached_network_image 2.5.1 [flutter flutter_cache_manager octo_image]
- cloud_firestore 1.0.1 [cloud_firestore_platform_interface cloud_firestore_web firebase_core firebase_core_platform_interface flutter meta]
- cupertino_icons 1.0.2
- firebase_auth 1.0.1 [firebase_auth_platform_interface firebase_auth_web firebase_core firebase_core_platform_interface flutter meta]
- firebase_core 1.0.1 [firebase_core_platform_interface firebase_core_web flutter meta]
- firebase_storage 8.0.0 [firebase_core firebase_core_platform_interface firebase_storage_platform_interface firebase_storage_web flutter]
- flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine]
- flutter_ffmpeg 0.3.1 [flutter]
- flutter_icons 1.1.0 [flutter]
- flutter_image_compress 0.7.0 [flutter]
- flutter_native_admob 2.1.0+3 [flutter]
- flutter_native_image 0.0.5+3 [flutter]
- flutter_spinkit 5.0.0 [flutter]
- flutter_widgets 0.1.12 [collection flutter html meta quiver]
- google_mobile_ads 0.11.0+3 [meta flutter]
- image_picker 0.7.2+1 [flutter flutter_plugin_android_lifecycle image_picker_platform_interface]
- international_phone_input 1.0.4 [flutter libphonenumber]
- intl 0.17.0 [clock path]
- intl_phone_field 1.4.4 [flutter]
- path_provider 2.0.1 [flutter path_provider_platform_interface path_provider_macos path_provider_linux path_provider_windows]
- progress_dialog 1.2.4 [flutter]
- provider 5.0.0 [collection flutter nested]
- scrollable_positioned_list 0.1.10 [flutter meta]
- shared_preferences 2.0.4 [meta flutter shared_preferences_platform_interface shared_preferences_linux shared_preferences_macos shared_preferences_web shared_preferences_windows]
- timeago 3.0.2
- transparent_image 1.0.0
- uuid 3.0.1 [crypto]
- video_player 1.0.1 [meta video_player_platform_interface video_player_web flutter]
- video_trimmer 1.0.0 [flutter video_player flutter_ffmpeg video_thumbnail path_provider intl path]

dev dependencies:
- flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel strin
g_scanner term_glyph typed_data]

transitive dependencies:
- archive 3.1.2 [crypto path]
- async 2.5.0 [collection]
- boolean_selector 2.1.0 [source_span string_scanner]
- characters 1.1.0
- charcode 1.2.0
- clock 1.1.0
- cloud_firestore_platform_interface 4.0.0 [collection firebase_core flutter meta plugin_platform_interface]
- cloud_firestore_web 1.0.1 [cloud_firestore_platform_interface firebase_core firebase_core_web flutter flutter_web_plugins js]
- collection 1.15.0
- crypto 3.0.0 [collection typed_data]
- csslib 0.16.2 [source_span]
- fake_async 1.2.0 [clock collection]
- ffi 1.0.0
- file 6.1.0 [meta path]
- firebase_auth_platform_interface 4.0.0 [firebase_core flutter meta plugin_platform_interface]
- firebase_auth_web 1.0.2 [firebase_auth_platform_interface firebase_core firebase_core_web flutter flutter_web_plugins http_parser intl js meta]
- firebase_core_platform_interface 4.0.0 [flutter meta plugin_platform_interface]
- firebase_core_web 1.0.1 [firebase_core_platform_interface flutter flutter_web_plugins js meta]
- firebase_storage_platform_interface 2.0.0 [collection firebase_core flutter meta plugin_platform_interface]
- firebase_storage_web 1.0.1 [async firebase_core firebase_core_web firebase_storage_platform_interface flutter flutter_web_plugins http js meta]
- flutter_blurhash 0.5.0 [flutter meta]
- flutter_cache_manager 2.1.2 [flutter path_provider uuid http path sqflite pedantic clock file rxdart image]
- flutter_plugin_android_lifecycle 2.0.0 [flutter]
- flutter_web_plugins 0.0.0 [flutter js characters collection meta typed_data vector_math]
- html 0.14.0+4 [csslib source_span]
- http 0.13.0 [http_parser meta path pedantic]
- http_parser 4.0.0 [charcode collection source_span string_scanner typed_data]
- image 3.0.1 [archive meta xml]
- image_picker_platform_interface 2.0.1 [flutter meta http plugin_platform_interface]
- js 0.6.3
- libphonenumber 1.0.2 [flutter meta]
- matcher 0.12.10 [stack_trace]
- meta 1.3.0
- nested 1.0.0 [flutter]
- octo_image 0.3.0 [flutter flutter_blurhash]
- path 1.8.0
- path_provider_linux 2.0.0 [path xdg_directories path_provider_platform_interface flutter]
- path_provider_macos 2.0.0 [flutter]
- path_provider_platform_interface 2.0.1 [flutter meta platform plugin_platform_interface]
- path_provider_windows 2.0.0 [path_provider_platform_interface meta path flutter ffi win32]
- pedantic 1.11.0
- petitparser 4.0.2 [meta]
- platform 3.0.0
- plugin_platform_interface 2.0.0 [meta]
- process 4.1.0 [file path platform]
- quiver 2.1.5 [matcher meta]
- rxdart 0.25.0
- shared_preferences_linux 2.0.0 [flutter file meta path path_provider_linux shared_preferences_platform_interface]
- shared_preferences_macos 2.0.0 [shared_preferences_platform_interface flutter]
- shared_preferences_platform_interface 2.0.0 [flutter]
- shared_preferences_web 2.0.0 [shared_preferences_platform_interface flutter flutter_web_plugins meta]
- shared_preferences_windows 2.0.0 [shared_preferences_platform_interface flutter file meta path path_provider_platform_interface path_provider_windows]
- sky_engine 0.0.99
- source_span 1.8.1 [collection path term_glyph]
- sqflite 2.0.0+2 [flutter sqflite_common path]
- sqflite_common 2.0.0+2 [synchronized path meta]
- stack_trace 1.10.0 [path]
- stream_channel 2.1.0 [async]
- string_scanner 1.1.0 [charcode source_span]
- synchronized 3.0.0
- term_glyph 1.2.0
- test_api 0.2.19 [async boolean_selector collection meta path source_span stack_trace stream_channel string_scanner term_glyph matcher]
- typed_data 1.3.0 [collection]
- vector_math 2.1.0
- video_player_platform_interface 2.2.0 [flutter meta]
- video_player_web 0.1.4+1 [flutter flutter_web_plugins meta video_player_platform_interface]
- video_thumbnail 0.2.5+1 [flutter]
- win32 2.0.4 [ffi]
- xdg_directories 0.2.0 [meta path process]
- xml 5.0.2 [collection meta petitparser]

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
bparrishMinescommented, Sep 8, 2021

@BrianTum

As @bennyng explained in https://github.com/googleads/googleads-mobile-flutter/issues/137#issuecomment-810038342:

Looks like the variable NativeAd _nativeAd; is being referenced to the same ad (the last loaded) where multiple list view items try to render it.

If any two AdWidgets in a ListView share a NativeAd, you will see this error. Each AdWidget must use a unique Ad.

Closing this issue as working as intended. Reopen if you are still receiving the error after making the suggested changes.

1reaction
bennyngcommented, Mar 30, 2021

Looks like the variable NativeAd _nativeAd; is being referenced to the same ad (the last loaded) where multiple list view items try to render it.

Having instances of completer and ad per load may solve this.

For example:

loadAd() {
    Completer<NativeAd> nativeAdCompleter = Completer<NativeAd>();

    final nativeAd = NativeAd(
      adUnitId: "ca-app-pub-3940256099942544/1044960115",
      request: AdRequest(),
      factoryId: 'adFactoryExample',
      listener: AdListener(
        onAdLoaded: (Ad ad) {
          print('$NativeAd loaded.');
          nativeAdCompleter.complete(ad as NativeAd);
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          ad.dispose();
          print('$NativeAd failedToLoad: $error');
          nativeAdCompleter.completeError(null);
        },
        onAdOpened: (Ad ad) => print('$NativeAd onAdOpened.'),
        onAdClosed: (Ad ad) => print('$NativeAd onAdClosed.'),
        onApplicationExit: (Ad ad) => print('$NativeAd onApplicationExit.'),
      ),
    );
    Future<void>.delayed(Duration(seconds: 1), () => nativeAd?.load());

    return nativeAdCompleter;
  }
case 'ad':
    final nativeAdCompleter = loadAd();

    return FutureBuilder<NativeAd>(
      future: nativeAdCompleter.future,
      builder: (BuildContext context, AsyncSnapshot<NativeAd> snapshot) {
        Widget child;

        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
          case ConnectionState.active:
            child = Container();
            break;
          case ConnectionState.done:
            if (snapshot.hasData) {
              child = AdWidget(ad: snapshot.data);
            } else {
              child = Text('Error loading $NativeAd');
            }
        }

        return Scaffold(
          body: Container(
            width: double.infinity,
            height: double.infinity,
            margin: EdgeInsets.only(top: 100, left: 5, right: 5, bottom: 70),
            child: Center(child: child),
            color: Colors.black,
          ),
        );
      },
    );
    break;
Read more comments on GitHub >

github_iconTop Results From Across the Web

Flutter: How to Properly Load Multiple Native Ads on Listview?
My goal is to show a Native ad every 8 ListTiles. Is there a way to properly do this without using extra packages?...
Read more >
[Native Ad]Loading Multiple Admob Native ads in Listview #568
Hi @ldobreira, Thanks for filing the issue. I can reproduce the issue when trying to load multiple native ads I get ad already...
Read more >
How to Properly Load Multiple Admob Native Ads on Listview?
My goal is to show a Native ad every 8 ListTiles. Is there a way to properly do this without using extra packages?...
Read more >
Implement Banner Ad between Listview items in a flutter.
flutter #flutterTutorial # listview #listviewseparated #bannerAds #AdmobAds#interstitialAds Show Ads between listview items in a flutter.
Read more >
Can we able to display multiple AdMob ads in list view
I have one app in which I want to display multiple ads in list view. App has one recycler view & which is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found