Load User-Specific Data from Dropbox upon Shiny App Launch ; outside server function

Hi Everyone,

I'm trying to use Dropbox for remote data storage for a shiny app (with user-authentication) I plan to host on shinyapps.io. The general approach is described here (thanks Dean!), using the rdrop2 R package. I have data for each user stored in a user-specific Dropbox folder. My goal is to import user-specific data from Dropbox upon app-launch, to be used in various reactive objects. The idea is to use a lookup-table to map a user to a Dropbox folder-name, where I'll import from.

Goal:

  • Detect the user
  • Map the user to a Dropbox folder using a lookup table
  • Import files (CSVs in my case) from that Dropbox folder into local storage for the user in-question
  • Use files in local storage for reactive objects (eg, reactiveFileReader() would depend on a local CSV-file)

I'm aware that session$user allows a shiny app with authentication to detect the user. However, my understanding is that calls to session$user must be contained within the server function, as session is an argument to server and cannot be referenced in global scope. Therefore, the derived user-specific Dropbox folder must be reactive in nature, and also contained within the server function. Consequently, files to be downloaded from Dropbox into local storage will not be present upon app launch. This is problematic as the app will crash.

Is there any way to address this? Specifically, I'm looking to detect the user and import the user-specific files before all reactives and observers are evaluated.

Thanks for your help,
Louis

Here's a sample app to show the full process:

library(shiny)
library(rdrop2)
library(shinydashboard)

# Dropbox folder, relative to root, which contains all user subfolders
core_folder <- "User Data"

# Lookup table to map user (session$user) to a code detailing a Dropbox subfolder name 
User_Info <- drop_read_csv(file = paste0(core_folder, "/", "User_Lookup.csv"))

# contents of User_Info file:
# User_Info <- data.frame(User = c("A", "B", "C"), User_Code = c(1,2,3))

######################## REMOTE TO LOCAL STORAGE ##################################################################

# Import data from Dropbox UPON APP LAUNCH from the appropriate user Dropbox folder
# Note that data.csv and df.csv could each hold any dataframe for purposes of this example

# Goal: Know the user-specific Dropbox folder upon app launch and import all necessary files, on which reactive objects depend, from said folder into local storage
# on shinyapps.io the directory would be the app directory, expressed as getwd()

# For example, fetch from user_specific_folder
# user_specific_folder <- paste0(core_folder, "/", user_code) , such that user_code is non-reactive 

drop_download(path = paste0(user_specific_folder, "/", "data.csv"), 
              overwrite = TRUE, local_path = getwd())

drop_download(path = paste0(user_specific_folder, "/", "df.csv"), 
              overwrite = TRUE, local_path = getwd())

# However, session$user leverages session, an argument to server
# Hence, user_code must be reactive: user_code() , and also defined within the scope of the server function
# Therefore, calls to drop_download() must be within the server function, causing the app to crash
# as the necessary files are not yet downloaded when the app is launched

############################## USER-INTERFACE #####################################################################

ui <- dashboardPage(
  skin = "blue",
  dashboardHeader(title = "Test App"),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
      menuItem("Widgets", tabName = "widgets", icon = icon("th"))
    )
  ),
  dashboardBody(
    tabItems(
      tabItem(
        tabName = "dashboard"
      ),
      tabItem(
        tabName = "widgets"
      )
    )
  )
)

##################################### SERVER ######################################################

server <- function(input, output, session) {
  
  # My understanding of the way to detect user, and derive the user-specific folder
  # However, files necessary to populate reactives will not be present in-time, and the app will crash
  
  user <- reactive({
    session$user
  })
  
  # Map user() to a user-code
  user_code <- reactive({
    User_Info[match(user(), User_Info$User),2]
  })
  
  # These two files must be loaded from Dropbox
  Initial_rv_State <- read.csv("data.csv", header = TRUE, sep = ",", na.strings = "")
  
  rv <- reactiveValues(current = Initial_rv_State)
  
  df <- reactiveFileReader(100, session = NULL, "df.csv", read.csv)
  
}

shinyApp(ui, server)

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.