Images uploaded through shiny FileInput unable to be accessed in LaTeX Rmarkdown

Hello everyone! I'll try to be as thorough as possible, as the issue I'm running into is a bit niche and I haven't been able to find any issues like it online.

My company outputs reports to clients that are iterative, with the same basic section repeating twice per page for any number of pages. In each of these sections, a different image is included that will vary each time the report is generated, meaning there are two different photos on each page. Because of this, I have created a pdf latex output that will generate these reports, looping through however many sections are needed and generating them in turn. The images are able to be uploaded through a shiny app that interfaces with the .Rmd document, and the image names are used to determine which section they are placed in.

The problem I'm running into has to deal with the dynamic nature of the file names. I am using the latex command \includegraphics in the for loop, and each time I loop through, I use paste0() to pass it a different image name. Though this works fine locally, it fails when deployed to shinyapps.io, erroring out with a 'file not found' error. The funny part is that if I hard code the file name (without using paste0()), it works just fine. However, since each section requires a different image, and thus, a different image name, this is not a solution and the image name does have to be different every time I loop through.

I have included a basic REPREX below. I have also deployed the shiny app (https://brendancambiumanalytica.shinyapps.io/AppEx/?_ga=2.35519585.1772078229.1637593808-468873122.1626364501), which will allow you to see that though it works fine locally, it fails when deployed.

Here is the shiny app code:

library(shiny)

ui <- fluidPage(
        fileInput('photos','Select Photos',accept=c('.jpg'),multiple=TRUE),
        downloadButton("output","Generate File")
)

server <- function(input, output, session){
    options(shiny.maxRequestSize=150*1024^2)
    output$output <- downloadHandler(
        filename = function(){
            paste0('File.pdf')
        },
        content = function(file){
            shiny::withProgress(
                message="Downloading",
                value=0,
                {
                    params <- list(photos=input$photos)
                    
                    shiny::incProgress(1)
                    
                    rmarkdown::render('LatexEx.Rmd',output_file=file,
                                      params=params,
                                      envir=new.env(parent=globalenv()))
                }
            )
        })

}

shinyApp(ui = ui, server = server)

And the .Rmd file:

---
title: 
output:
  pdf_document: 
    latex_engine: xelatex
header-includes:
  - \usepackage{multicol}
  - \usepackage{graphicx}
  - \usepackage{background}
params:
  photos: NA
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE,warning=FALSE,message=FALSE)
library(tidyverse)
library(tinytex)
library(knitr)
photos <- params$photos
dir.create("Photos")

for(i in 1:nrow(photos))
{
  file.copy(photos$datapath[i],paste0("./Photos/",photos$name[i]))
  cat("\\includegraphics[width=4cm,height=4cm]{",paste0("./Photos/",photos$name[i]),"}") #Fails when deployed
  
  #file.copy(photos$datapath[i],paste0("./Photos/file.jpg"))
  #cat("\\includegraphics[width=4cm,height=4cm]{./Photos/file.jpg}") #Works when deployed, but doesn't iterate
}

Any help you can offer will be greatly appreciated. This discrepancy, which seems to just come from paste0(), is driving me mad!

Hey BLukomski, that's quite an interesting issue you're running into! It sounds like Shinyapps.io is being a bit picky with file paths. Have you tried debugging with absolute paths instead of relative ones when using paste0()? Sometimes the deployment environment might handle things differently from local. Also, is there a chance the dynamic images are not being uploaded properly before LaTeX tries to access them? Maybe adding a check or delay could help. By the way, troubleshooting these quirks can sometimes feel like dealing with funny puns https://allfunnypuns.com/ —you think it’ll work, but it keeps giving unexpected results! Would love to hear how it gets resolved!