androidflutterdartflutter-streambuilder

Why doesnt the StreamBuilder update the PDFView widget?


Im new to flutter and stuck at the following problem, hope someone can help:

I am trying to build an App where the Presenter opens a pdf file and the Viewer can join the Presentation. The viewer gets the PDF file, opens it, and gets constant updates on the currently opened page (from the Presenter).

I set up a firebaseauth, firebase realtime database and firebase storage, authenticating the user throug a login, uploading and downloading the pdf to storage and writing the currentPage into realtime database. This part is working fine.

I am currently stuck for days at my pdf viewer client part, where i wrapped a StreamBuilder around the PDF Widget from the flutter_pdfview package, expecting it to update the Page opened by the widget.The Stream listens to the database entry written from the presenter "page".

body: StreamBuilder(
          stream: _firestore
              .collection('pdfControl')
              .doc(loggedInUser.uid)
              .snapshots(),
          builder: (context, snapshot) {
            if (snapshot.hasData && snapshot.data != null) {
              print(snapshot.data?['page']);
              var page = snapshot.data!['page'];
              currentPage = page;
              print ('currentpage:  $currentPage');
              //_pdfController.setPage(page);

              return PDFView(

I did try to check if i get changes from the realtimedb snapshot.

`if (snapshot.hasData && snapshot.data != null) {
              print(snapshot.data?['page']);`

is working. The Output is 1, 2, 3, 2 etc

But the

`return PDFView(
                  filePath: widget.pdfPath,
                  autoSpacing: true,
                  enableSwipe: true,
                  pageSnap: true,
                  swipeHorizontal: true,
                  defaultPage: currentPage!,
                  onError: (error) {
                    print(error);
                  },
                  onPageError: (page, error) {
                    print('$page: ${error.toString()}');
                  },
                  onRender: (_pages) {
                    setState(() {
                      pages = _pages!;
                      isReady = true;
                      print ('currpage:  $currentPage');
                    });
                  },
                  onViewCreated: (PDFViewController vc)  {
                    setState(() {
                      _pdfController = vc;
                      _controller.complete(vc);
                      vc.setPage(currentPage);
                      print(page);
                      print(snapshot.data?['page']);
                    });

                  },
                  onPageChanged: (int? page, int? total) {
                    setState(() {
                      currentPage = page!;
                    });

                  });`

It is not swaping the page. when the snapshot.data?['page'] gets an update.

Why?

I thought the StreamBuilder would listen on the

stream: _firestore
              .collection('pdfControl')
              .doc(loggedInUser.uid)
              .snapshots(),

and rebuilds the widgets it is wrapped around on changes in the db collection?

`I/flutter (12485): currentpage:  3
E/FrameEvents(12485): updateAcquireFence: Did not find frame.
E/FrameEvents(12485): updateAcquireFence: Did not find frame.
I/flutter (12485): 3
I/flutter (12485): currentpage:  3
E/FrameEvents(12485): updateAcquireFence: Did not find frame.
I/chatty  (12485): uid=10123(com.example.screenshare_project) RenderThread identical 21 lines
E/FrameEvents(12485): updateAcquireFence: Did not find frame.
I/flutter (12485): 4
I/flutter (12485): currentpage:  4
I/flutter (12485): 4
I/flutter (12485): currentpage:  4
I/flutter (12485): 3
I/flutter (12485): currentpage:  3
I/flutter (12485): 3
I/flutter (12485): currentpage:  3`

this is my output

I really need some help here...can someone please explain this behavior to me? What am i doing wrong?

PS: The setState lines are my desperate attempt for another solution (not working)


Solution

  • defaultPage is only used at the time the PDF file is loaded, after that it won't control what page is currently being displayed.

    Use the controller to change the page.

    _pdfController.setPage(page);
    

    Also you don't need to wrap PDFView inside a StreamBuilder. Just listen to the stream with the listen method, and call that setPage method in the callback.