skip to Main Content

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)

2

Answers


  1. Chosen as BEST ANSWER

    I was able to solve it with implementing the suggestions from Dhafin Rayhan:

    (StreamBuilder to listener and nullable PDFViewController):

    PDFViewController? _pdfController;
    
    @override
      void initState() {
        super.initState();
        getCurrentUser();
    
        _firestore
            .collection('pdfControl')
            .doc(loggedInUser.uid)
            .snapshots()
            .listen((snapshot) {
          var page = snapshot.data()?['page'];
          print(page);
          _pdfController?.setPage(page);
        });
    
    @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: PDFView(
              filePath: widget.pdfPath,
              autoSpacing: true,
              enableSwipe: true,
              pageSnap: true,
              swipeHorizontal: true,
              onError: (error) {
                print(error);
              },
              onPageError: (page, error) {
                print('$page: ${error.toString()}');
              },
              onRender: (page) {
                
              },
              onViewCreated: (PDFViewController vc) {
                _controller.complete(vc);
                _pdfController = vc;
                
              },
              onPageChanged: (int? page, int? total) {
                
              },
            ),
          ),
        );
      }
    

    Thanks a lot!


  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search