Shinyapps.io Non-interactive auth fails for googledrive

Hello all,
using google-fu on my Shinyapps.io error code initially brought me to this post but unlike @Massimo66 I have never been able to have my shiny app to work.

I followed the vignette on how to set up Non-interactive auth in gargle using the Project-level OAuth cache but after deployment I get the error: "An error has occurred
Unable to connect to worker after 60.00 seconds; startup took too long."

When I look at the log, I see that Shiny app is stalled waiting for authentication in a browser.
2019-12-05T01:55:09.795323+00:00 shinyapps[154862]: no matching token in the cache
2019-12-05T01:55:09.704587+00:00 shinyapps[154862]: Attaching package: ‘googlesheets4’
2019-12-05T01:55:09.800338+00:00 shinyapps[154862]: Waiting for authentication in browser...
2019-12-05T01:55:09.800503+00:00 shinyapps[154862]: Press Esc/Ctrl + C to abort
2019-12-05T01:55:09.805120+00:00 shinyapps[154862]: Please point your browser to the following url:
2019-12-05T01:55:09.805300+00:00 shinyapps[154862]: https://accounts.google.com/o/oauth2/auth?client_id=.....

Here's my R code

library(shiny)
library(tidyverse)
library(hms)
library(googledrive)
library(googlesheets4)

#troubleshoot
options(gargle_quiet = FALSE)

#authenticate into Google Drive ### NOT QUITE WORKING YET in non-interactive mode ##
#In Rstudio, running this code brings me to my web browser to allow tidyverse access
#then it put a token into the cache, now I have two tokens in there
drive_auth(cache = ".secrets", 
           email = TRUE) 

sheets_auth(token = drive_token(),
            scopes="https://www.googleapis.com/auth/spreadsheets.readonly")

# read the Spawning google sheet by ID
sheets_get("1OgmHW3f9O3HHqp-5PK8jEj9vDwVHg1oTMw81Qg2GQkE")
SpawnDF <- read_sheet("1OgmHW3f9O3HHqp-5PK8jEj9vDwVHg1oTMw81Qg2GQkE", sheet = 1, col_types = "c", na = "")

#convert dates from character to date class
SpawnDF$DATE=as.Date(SpawnDF$DATE, "%m-%d-%Y") #updated column header

#Fix Total # of tanks to numeric vector
SpawnDF$`Total # of tanks` <- as.numeric(SpawnDF$`Total # of tanks`)

ui <- fluidPage(
  tags$h2("Frequency of Aiptasia spawning in Pringle Lab"),
  column(3,       
         dateRangeInput(inputId = "daterange", label = "Enter a date range", 
                 format = "yyyy-mm-dd", start = "2016-01-01"),
         
         br(),
         
         submitButton("Submit")
         ),
  column(9,
         plotOutput(outputId = "spawnplot"),
         
         br(),
         #print("last updated 2019-11-12")
         print("The spawning app now directly reads from our data server & thus updates in real time. \n software v.2019-12-04")
  )
  
)

server <- function(input, output){
  output$spawnplot <-renderPlot({ 
    
      SpawnDF %>% 
        filter(DATE >= input$daterange[1] & DATE <= input$daterange[2]) %>% 
        group_by(DATE, `Total # of tanks`) %>% 
        count(`Spawn Type`) %>%
        mutate(norm.Count = n/ `Total # of tanks` )  %>%
        ggplot( aes(x=DATE, y= norm.Count, fill=`Spawn Type`) ) +
        geom_bar(stat = "identity") +
        ylab("normalized counts") + 
        theme_bw()+ theme(text = element_text(size = 16))  
    })
}

shinyApp(ui = ui, server = server)

R session info

> sessionInfo()
R version 3.3.3 (2017-03-06)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: macOS  10.15.1

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] googlesheets4_0.1.0 googledrive_1.0.0   hms_0.5.1           forcats_0.2.0       stringr_1.2.0      
 [6] dplyr_0.8.3         purrr_0.3.3         readr_1.1.1         tidyr_0.7.2         tibble_2.1.3       
[11] ggplot2_3.2.1       tidyverse_1.2.1     shiny_1.4.0        

loaded via a namespace (and not attached):
 [1] tidyselect_0.2.5 gargle_0.4.0     haven_1.1.0      lattice_0.20-34  colorspace_1.3-2
 [6] generics_0.0.2   vctrs_0.2.0      htmltools_0.4.0  yaml_2.2.0       rlang_0.4.2     
[11] later_1.0.0      pillar_1.4.2     glue_1.3.1       withr_2.1.2      modelr_0.1.1    
[16] readxl_1.0.0     plyr_1.8.4       munsell_0.5.0    gtable_0.2.0     cellranger_1.1.0
[21] rvest_0.3.2      fastmap_1.0.1    httpuv_1.5.2     curl_3.0         broom_0.5.2     
[26] Rcpp_1.0.2       xtable_1.8-4     openssl_0.9.9    promises_1.1.0   scales_0.5.0    
[31] backports_1.1.1  jsonlite_1.5     fs_1.3.1         mime_0.5         digest_0.6.12   
[36] stringi_1.1.5    grid_3.3.3       cli_1.1.0        tools_3.3.3      magrittr_1.5    
[41] lazyeval_0.2.1   crayon_1.3.4     pkgconfig_2.0.3  zeallot_0.1.0    rsconnect_0.8.15
[46] xml2_1.1.1       lubridate_1.7.1  assertthat_0.2.0 httr_1.4.1       rstudioapi_0.7  
[51] R6_2.4.0         nlme_3.1-131    

The gargle doc says:

Setting the option gargle_oauth_email = TRUE says that googledrive is allowed to use a token that it finds in the cache, without interacting with a user, as long as it discovers EXACTLY one matching token.

What happens when you only have one token?

AH, thanks so much! was banging my head against the wall for so long and just totally passed over the part of the documentation where it tells you.
"Two main principles:

  1. Take charge of – or at least notice – the folder where OAuth tokens are being cached.
  2. Make sure exactly one cached token will be identified and pre-authorize its use."

Removed all tokens from my .secrets folder. Re-authenticated in interactive mode ONCE & stored token in correct folder. Then commented out those lines. Now it works in Non-interactive mode.

2 Likes

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