Additional notes:
The filter itself still works; only the text is not displayed.
The issue occurs across all reports, not just specific ones.
If anyone knows the cause, I’d really appreciate your help.
]]>If you’d like to use Google Sheets functions such as QUERY()
, FILTER()
, or REGEXMATCH()
to search and analyze the CSV files produced by the AppSheet Parser Suite, this script can save you a lot of manual work.
AppSheet’s HTML export, once parsed by the Parser Suite, produces several CSVs (appsheet_columns.csv
, appsheet_views.csv
, etc.).
Analyzing relationships or searching across them inside Google Sheets can be powerful, but importing each file by hand is tedious and error-prone.
This Google Apps Script automatically creates a Google Sheets file containing the parsed data from your app. Expressions are brought into the file as text to prevent errors and ensure that they will be searchable. Once converted to a Google Sheets file, you can use spreadsheet tools (QUERY
, FILTER
, BYROW
, etc.) to explore your app.
Before running the script, upload your parsed CSV files to Google Drive:
https://drive.google.com/drive/folders/1A2b3C4D5E6F7G8H9I0J
const folderInput = "PASTE_YOUR_FOLDER_URL_OR_ID_HERE";
// --- begin script ---
/**
* Import all CSV files from a Google Drive folder into one spreadsheet.
* - Spreadsheet name = folder name (exactly)
* - Sheet names = CSV file names (without .csv)
* - All values imported as literal text
* - Result link shown in Execution Log
*/
function importCSVsFromFolderDirect() {
const folderInput = "PASTE_YOUR_FOLDER_URL_OR_ID_HERE";
const folderId = extractFolderId(folderInput);
if (!folderId) {
Logger.log("❌ Invalid folder URL or ID. Please check the line near the top of the script.");
return;
}
const link = importCSVsFromFolder(folderId);
Logger.log("✅ Done! Created spreadsheet: " + link);
}
function importCSVsFromFolder(folderId) {
const folder = DriveApp.getFolderById(folderId);
const folderName = folder.getName();
const ss = SpreadsheetApp.create(folderName);
const files = folder.getFiles();
let csvCount = 0;
while (files.hasNext()) {
const file = files.next();
const name = file.getName();
if (!/\.csv$/i.test(name)) continue;
const text = stripBOM(file.getBlob().getDataAsString('UTF-8'));
const delimiter = detectDelimiter(text);
const rows = Utilities.parseCsv(text, delimiter) || [];
// Treat all cells as literal text
const safeRows = rows.map(row =>
row.map(cell => {
let value = String(cell);
if (/^[=+]/.test(value)) value = "'" + value; // escape formulas
return value;
})
);
const sheetName = makeUniqueSheetName(ss, sanitizeSheetName(name.replace(/\.csv$/i, '')));
const sheet = ss.insertSheet(sheetName);
const range = sheet.getRange(1, 1, Math.max(1, safeRows.length), Math.max(1, safeRows[0]?.length || 1));
range.setNumberFormat('@');
if (safeRows.length > 0 && safeRows[0].length > 0) {
range.setValues(safeRows);
}
csvCount++;
}
const defaultSheet = ss.getSheets()[0];
if (defaultSheet.getDataRange().getValue() === '') ss.deleteSheet(defaultSheet);
if (csvCount === 0) Logger.log("⚠️ No CSV files found in this folder.");
return ss.getUrl();
}
/** ---------- Helpers ---------- **/
function extractFolderId(input) {
const urlMatch = input.match(/\/folders\/([a-zA-Z0-9_-]+)/);
if (urlMatch) return urlMatch[1];
const qMatch = input.match(/[?&]id=([a-zA-Z0-9_-]+)/);
if (qMatch) return qMatch[1];
if (/^[a-zA-Z0-9_-]{20,}$/.test(input)) return input;
return null;
}
function stripBOM(text) {
return text.charCodeAt(0) === 0xFEFF ? text.slice(1) : text;
}
function detectDelimiter(text) {
const firstLine = (text.split(/\r?\n/).find(l => l.trim().length) || '');
const counts = { ',': (firstLine.match(/,/g) || []).length, '\t': (firstLine.match(/\t/g) || []).length, ';': (firstLine.match(/;/g) || []).length };
let best = ',', max = -1;
for (const d in counts) if (counts[d] > max) { max = counts[d]; best = d; }
return best;
}
function sanitizeSheetName(name) {
let n = name.replace(/[\[\]\:\*\?\/\\]/g, ' ');
if (n.length > 100) n = n.slice(0, 100);
return n.trim() || 'Sheet';
}
function makeUniqueSheetName(ss, base) {
let name = base, i = 2;
while (ss.getSheetByName(name)) {
const suffix = ' (' + i + ')';
const head = base.length + suffix.length > 100 ? base.slice(0, 100 - suffix.length) : base;
name = head + suffix;
i++;
}
return name;
}
// --- end script ---
CSV Folder Importer
.const folderInput = "PASTE_YOUR_FOLDER_URL_OR_ID_HERE";
Paste your Google Drive folder URL or ID between the quotes.
https://drive.google.com/drive/folders/1A2b3C4D5E6F7G8H9I0J
importCSVsFromFolderDirect
, then click the ✅ Done! Created spreadsheet: https://docs.google.com/spreadsheets/d/xxxxxxxxxxxx/edit
Once you have the combined Google Sheet, you can use spreadsheet formulas to explore your AppSheet data.
Tip: Once you’ve verified that everything imports correctly, you can reuse this script anytime—just change the folder URL near the top and run it again to generate a fresh Google Sheet for new projects or new versions of the same project.
P.S. To save time, I used ChatGPT to prepare this post and the script. I have confirmed that the script works with my own data and I have read and revised the text of this post to my satisfaction. Any remaining problems are my fault, of course, not the responsibility of any AI tool I used.
]]>I’m using the list_chunks
method from the Discovery Engine API (Gemini Enterprise Plus), but it doesn’t return the page number (page_identifier
) for each chunk.
I need to know which page each chunk belongs to because I’m summarizing a large number of PDFs through the API.
I’m using the API instead of the Gemini Enterprise chat interface because the chat often fails to find all the content from all PDFs — I need to summarize using the complete text of every document, not just the most relevant parts.
Is there any way to retrieve the page number when listing chunks, or a configuration that enables this?
Thanks in advance!
chunk_client = de_v1alpha.ChunkServiceClient()
all_chunks = []
request = de_v1alpha.ListChunksRequest(parent=document_name, page_size=1000)
page_result = chunk_client.list_chunks(request=request)
for chunk in page_result:
all_chunks.append(chunk)
return all_chunks
]]>I am encountering a persistent error when creating AppSheet applications, which prevents the editor and preview from loading successfully.
Problem Description: After creating an app (either by connecting existing data or by creating a blank app and then adding data manually), the app preview consistently displays the following error:
Error
The [AppName-xxxxx] app did not load successfully. Please contact the app creator.
Unable to fetch app definition. App '[AppID]' version '1.00000x' is not runnable -
The issue does not seem related to data complexity or the specific Google account used. It occurs even in the simplest possible scenario (blank app + new basic spreadsheet) across two different Google accounts.
This strongly suggests a potential issue with the AppSheet platform itself during the initialization phase of the app definition within my environment.
Could you please help with this issue?
]]>I urgently need help with a broken organization resource that’s preventing access to GCP support and blocking our security implementation.
CRITICAL ISSUE:
After verifying our domain empathos.ai in Cloud Identity 40+ hours ago, the organization resource was not properly created. Instead, a broken resource stub exists:
This broken resource is blocking:
ACCOUNT INFORMATION:
TROUBLESHOOTING COMPLETED:
✓ Domain fully verified in Cloud Identity admin console
✓ Cloud Resource Manager API enabled
✓ Billing account active and linked to project
✓ Tested with both super admin and project owner accounts
✓ gcloud organizations list returns empty array
✓ GCP Console shows broken org resource with ID: 0
BUSINESS IMPACT:
We need to implement domain-restricted authentication policies (iam.allowedPolicyMemberDomains) to prevent former collaborators from accessing Empathos.ai resources. This critical security implementation is completely blocked without a functioning organization resource.
REQUEST:
Please investigate the broken organization resource for Customer ID (PII Removed by Staff) and:
This appears to be a backend provisioning failure. The broken resource stub suggests the initial organization creation failed partway through.
Attached: Screenshot showing broken organization resource
Thank you for your urgent assistance.
Mitchell R.
(PII Removed by Staff)
though this season I am aiming for top tier and hope that the prices won’t just be repeated and a bit personalized
]]>I have raised a ticket with the support team for you. I will monitor the same and come back to you.
]]>On the actual mobile app, it’s just not there.
And this settings for it ….
]]>Build a public app that has access to the table containing the data of interest (from appsheet) which I believe the student could download (or access). from this, I believe, they could access their data realtime instead of waiting for an email that may not deliver.
]]>Thanks
(attachments) (click for more details) ]]>But the same thing when tried from my Java SDK code which is my actual requirement
I get this
Required ‘read’ permission for ‘${filepath}/alma-test.raw.tar.gz’
well I have the required access as Project Owner , Storage Object Viewer , Storage Admin for my service account
ref code :
Image newImage = new Image()
newImage.setName(googleImageName)
Image.RawDisk rawDisk = new Image.RawDisk()
rawDisk.setSource(sourceUrl)
newImage.setRawDisk(rawDisk)
def scopes = new ArrayList()
scopes << ComputeScopes.COMPUTE
scopes << StorageScopes.DEVSTORAGE_READ_WRITE
computeClient = getGoogleComputeClient(opts.zone, scopes)
Compute.Images.Insert insertImage = computeClient.images().insert(projectId, newImage)
def insertResult = insertImage.execute()
The compute client which is used above is also used for other sdk calls which eventually works fine
Request help here if it was some kind of permission error the rest api shouldn’t have worked & if any explicit permissions are required at a service account level or at a storage bucket level
Hi there, did you get at least a warning mail or a given period to take action?
Actually the way your blocked is unacceptable!
]]>I am not aware of any kind of “key” that allows for free upgrading within AppSheet. Either you mis-understood or were lied to.
Billing is quite simple in AppSheet. All non-deployed apps are free and allow UP TO 10 test users.
Deployed apps require a license for each user that accesses the app monthly and that license level is determined based on the features you have integrated into the app. Each app has a feature built into it where you can inspect what the required license level will be once the app is deployed.
Once an app is deployed and has incurred licensing fees, those fees are not automatically erased or changed just because you changed the state to a non-deployed app. You MUST contact AppSheet support and they should help you get your app re-instated.
You can find the Help menu option in the upper-right hand menu of the App Editor.
I hope this helps!
]]>Refer to this article for more details - Use Start expressions in templates
]]>We’ve seen that your question hasn’t gotten a response yet. We’ll keep checking in on this thread and encourage other members to share their thoughts
It doesn’t matter whether I select Primary, Prominent or Inline. It never shows on the mobile (Android) devise. All other functions work beautifully.
]]>ut when I upload that certificate to Apigee, configure the Target Server, aliases etc. and test it, I get an error “SSL Handshake failed null”.
Can you please provide more details specifically around “upload” and “configure”? Be specific.
What did you do? How did you configure it? Show the Target Server configuration. Explain what you did with keys and certs. Be explicit.
As far as I know, yes.
The .p12 format usually contains the key and the cert. Did you upload that .p12 file into Apigee, and if so, can you explain specifically how you did that?
]]>@ilnardo92 - appreciate your guidance!
]]>Yes I embed images using standard markdown syntax:

Whenever I use above syntax and try to open detail view with markdown enabled in longtext field, the app crashes as showed on my previous gifs. I should be more precise and forgot I can type this in a code block here on the community. Sorry for the confusion.
Let me know what else I should prepare to help you reproduce this issue, please.
Are these public urls? If it’s not sensitive info would you be able to share an example of a specific url that crashes? If you swap in some other public url, like some image from wikimedia commons, does that still crash as well? I’m not seeing any problem on my Android phone when using that kind of public image with this pattern.
I would suggest to create a support ticket where you can include private details like the account ID and name of the app and then let me know the case number, that would enable me to search our error logs for the specific app involved.
]]>I think appsheet team should clarify this and explain clearly why many people’s app were blocked recently
Thanks in advance
]]>The group headers/title do not show when a group is clicked and expanded. It shows in other modes (the default and PC modes). I really appreciate the efforts of the team. Thank you.
Thanks for the kind words. There is unfortunately a lot of variation now in what headers are shown or not shown with grouped/drilldown views in various contexts (top-level vs inline/in dashboard, new mobile vs old mobile vs desktop). Just to be sure I understand the request, can you include screenshots illustrating the problem (without personal info) and your grouping configuration?
]]>I am the super-administrator of a new Google Workspace organization and I am completely deadlocked by a security policy. I have tried every documented method to solve this and would be extremely grateful for any help.
Goal:
Trigger a Cloud Function (Gen 2) when a new email arrives in my Workspace Gmail account.
Core Problem:
The iam.allowedPolicyMemberDomains organization policy is active and prevents any identity outside my organization from being granted IAM roles. This blocks all event-driven triggers for my Cloud Function.
What I have tried:
Gmail API Push to Pub/Sub: Fails because the Gmail service account (gmail-api-push@system.gserviceaccount.com) cannot be granted the pubsub.publisher role. The attempt to add this permission results in a FAILED_PRECONDITION error due to the organization policy.
Editing the Organization Policy (as orgpolicy.policyAdmin
): I have the roles/orgpolicy.policyAdmin role. I have tried to edit the iam.allowedPolicyMemberDomains policy to add an exception. Both the web console and gcloud reject every possible syntax (serviceAccount:…, domain:…, under:cloudidentity…) with an “Invalid value” error.
Temporarily Disabling the Policy at the Project Level: I attempted the standard workaround to temporarily disable the policy on the project, grant the permission, and then re-enable it.
Authenticated Pub/Sub Push Subscription: I created a push subscription that uses a service account from my own project (with run.invoker role) to call the Cloud Function’s HTTP endpoint. This also fails, with the function logs showing The request was not authenticated.
Allowing Unauthenticated Invocation: Deploying the function with --allow-unauthenticated fails with the same FAILED_PRECONDITION error, as the organization policy blocks adding allUsers to the IAM policy.
Conclusion:
I am in a complete deadlock. It seems impossible to either (a) grant the necessary cross-service permissions or (b) disable the policy that prevents it, even temporarily at a project level. This seems to be a common issue for new Google Workspace organizations with default security policies.
Question:
Is there a known, working procedure for new Google Workspace organizations to allow Google’s own services (like Gmail API push) to interact with project resources when this restrictive policy is active? How can I correctly configure an exception to the iam.allowedPolicyMemberDomains policy?
Thank you for any guidance.
]]>I’d like to report a bug for the new mobile framework here. If the form’s “Auto re-open” is enabled, after I click Save it would give me this error:
This one has been fixed, it should be working now.
]]>i’m trying to create a basic template to generate pdf of all the records.
i wrote this simple template:
<<Start: Patient>>
ZehutNum: <<[ZehutNum]>>
LastName: <<[LastName]>>
FirstName: <<[FirstName]>>
MiddleName: <<[MiddleName]>>
AddressDetails: <<[AddressDetails]>>
AddressCity: <<[AddressCity]>>
DateOfBirth: <<[DateOfBirth]>>
MaritalStatus: <<[MaritalStatus]>>
ChildrenNum: <<[ChildrenNum]>>
HelathInsurance: <<[HelathInsurance]>>
Email: <<[Email]>>
CellPhone: <<[CellPhone]>>
CountryOfBirth: <<[CountryOfBirth]>>
Age: <<[Age]>>
BirthYear: <<[BirthYear]>>
<>
the “Save” button - return an error with the alert:
Task ‘Generate PDF’ Body template. Expression ‘Patient’ is invalid due to: Constant text “Patient” should not be wrapped in “<<” “>>”.
im using google docs for the documents and templates.
where was i wrong?
From some reason it doesn’t let me write the word “End” in the Forum
]]>The NotebookLM API documentation for adding video sources shows an incorrect field name. The documentation states url
should be used, but the actual API requires youtubeUrl
.
The documentation shows:
"videoContent": {
"url": "URL_YOUTUBE"
}
However, this does not work with the actual API.
url
) - FAILSRequest:
curl -X POST \
"https://global-discoveryengine.googleapis.com/v1alpha/projects/PROJECT_NUMBER/locations/global/notebooks/NOTEBOOK_ID/sources:batchCreate" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"userContents": [
{
"videoContent": {
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}
}
]
}'
Response (Error):
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"url\" at 'user_contents[0].video_content': Cannot find field.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "user_contents[0].video_content",
"description": "Invalid JSON payload received. Unknown name \"url\" at 'user_contents[0].video_content': Cannot find field."
}
]
}
]
}
}
youtubeUrl
) - SUCCEEDSRequest:
curl -X POST \
"https://global-discoveryengine.googleapis.com/v1alpha/projects/PROJECT_NUMBER/locations/global/notebooks/NOTEBOOK_ID/sources:batchCreate" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"userContents": [
{
"videoContent": {
"youtubeUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}
}
]
}'
Response (Success):
{
"sources": [
{
"sourceId": {
"id": "d9c2b9d4-6c3e-4516-a713-ef7315b93de8"
},
"title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
"metadata": {
"wordCount": 487,
"tokenCount": 633
},
"settings": {
"status": "SOURCE_STATUS_COMPLETE"
}
}
]
}
The documentation should be updated to show the correct field name:
"videoContent": {
"youtubeUrl": "URL_YOUTUBE"
}
This discrepancy makes it difficult for developers to integrate with the API, as following the documentation results in API errors. The correct field name was discovered through trial and error.
]]>if I did the Gmail account which owns all apps, this would then break the apps for all other users?
Purchasing a single Enterprise license would not immediately break or block access to the apps for the other users; however, this action will trigger warnings and sharing violations that administrators will see in the AppSheet Admin Console. It is them important to consider that:
The reason is that even if the Enterprise creator builds an app using only Core functionality, the Enterprise Plus license automatically confers enterprise features (like audit history, versioning, and performance enhancements) to all apps owned by that creator.
]]>Vision: Teachers can easily track behaviors and award points for positive behaviors, students and parents can check their performance and set goals. Admin can easily pull student behavior data for decisions.
Mission: Make a database app so teachers can award points for positive behavior and document behavioral issues. Create admin and student views.
Current: Appsheet database with multiple tables and relationships. Everything is working great except students seeing their data. Students can’t login to the app, so I setup a bot to get the necessary data emailed to them, but only 50-100 of the 700 are going through. Appsheet says they went, and our organizations email filter did not block them. It’s all internal to our Google Workspace.
Scope: My school, 700+ kids and 40+ Teachers/admin
Timeline: It’s already deployed and operational. Everything is great except the emailed reports.
]]>This will be out-rolled slowly, and implemented completely in Aug 2026 according to the timeline in this article: Planning for the deprecation of single-factor password sign-ins | Snowflake Documentation
But just wondering if this was something you are considering and/or aware of. Would really love continuing to use this connection on my reports! Thank you
]]>@looker/embed-sdk
library and have encountered an issue. Some users experience persistent flickering and re-rendering of the embedded charts, which makes them essentially unusable (I’ve attached a video demonstrating this behavior).
Here’s what we know so far:
The issue only affects a subset of users and we can’t reproduce it internally.
We’re using the latest version of @looker/embed-sdk
.
The flicker happens consistently for those affected, causing major disruption.
We’ve tried to debug but are stuck since we can’t recreate the problem on our end.
Our questions for the community:
What are the best debugging approaches when you can’t reproduce an issue locally?
Are there any known issues with chart flickering or re-rendering in the @looker/embed-sdk
?
Any advice on logging or tracing to better diagnose embedded React charts in production environments?
Video of issue - https://drive.google.com/file/d/1Zx1xOuYk4peY_nCOL1RJQl8LdkCyrf-J/view?usp=sharing
]]>SVG Gantt built from data, original done by @Kabulino
]]>Hello @Sonlehust,
Thanks for bringing this to our attention. Let me investigate and I’ll come back to you ASAP.
]]>I’ve seen it, it looks great, the setup is fairly complicated due to the relationships between the entities, so we are looking at ways to automate/streamline the initial setup.
As far as localization, I know we’ve been making headway, but I just want to be clear that we are focusing on the creator UI, not adding the ability to have apps in multiple languages. It’s already possible to have strings in other languages for an app, but there are a few edges - dates, the browser language setting, etc and we’re working our way through those as well.
]]>