The storage is limited to the device's storage.
It is working now.
Thank you so much!
I added a "Forgot Password" button, and added some blocks, updated and redeployed the App script again and again. but I couldn't find the mistake.
I was stuck at "Searching for password"
here is my script
// Set up the ID of your Google Sheet. You can get this from the sheet URL.
// Sheet ID is updated to the new URL provided by the user: 1_EfSGxVRjjRvk_T_i-OmPYfuAv5ecyTbak2qcFhz5gw
const SPREADSHEET_ID = '1_EfSGxVRjjRvk_T_i-OmPYfuAv5ecyTbak2qcFhz5gw';
const SHEET_NAME = 'Sheet1'; // Assuming your sheet is named 'Sheet1'
/**
- Handles HTTP GET requests for user login verification and password retrieval (Forgot Password).
- Expected parameters: action=login/forgot, username, password (for login only)
*/
function doGet(e) {
const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
const data = sheet.getDataRange().getValues();
const users = data.length > 1 ? data.slice(1) : ; // Actual user data rows
const action = e.parameter.action;
const username = e.parameter.username;
// === 1. FIND USER AND PASSWORD (Shared logic for login and forgot) ===
let foundPassword = null;
// Iterate through existing users to check credentials
for (let i = 0; i < users.length; i++) {
const storedUsername = users[i][0];
if (storedUsername === username) {
// Assuming password is in the second column (index 1)
foundPassword = users[i][1];
break;
}
}
// === 2. HANDLE LOGIN ACTION ===
if (action === 'login') {
const password = e.parameter.password;
if (!username || !password) {
return ContentService.createTextOutput("Error: Missing username or password for login.")
.setMimeType(ContentService.MimeType.TEXT);
}
// Check credentials against the found password
if (foundPassword && foundPassword === password) {
return ContentService.createTextOutput("Login Success")
.setMimeType(ContentService.MimeType.TEXT);
}
return ContentService.createTextOutput("Invalid Credentials")
.setMimeType(ContentService.MimeType.TEXT);
}
// === 3. HANDLE FORGOT PASSWORD ACTION ===
else if (action === 'forgot') {
if (!username) {
return ContentService.createTextOutput("Error: Missing username for password retrieval.")
.setMimeType(ContentService.MimeType.TEXT);
}
if (foundPassword) {
// SUCCESS: Return the password using the unique identifier text for App Inventor
return ContentService.createTextOutput("Your password is: " + foundPassword)
.setMimeType(ContentService.MimeType.TEXT);
} else {
// FAILURE: Username not in the database
return ContentService.createTextOutput("Username not found.")
.setMimeType(ContentService.MimeType.TEXT);
}
}
// Default response for other GET requests
return ContentService.createTextOutput("Welcome to the User Auth API.")
.setMimeType(ContentService.MimeType.TEXT);
}
/**
- Handles HTTP POST requests for user registration (using the successful, simpler logic).
- Expected parameters: action=register, username, password
*/
function doPost(e) {
const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
const action = e.parameter.action;
if (action === 'register') {
const username = e.parameter.username;
const password = e.parameter.password;
if (!username || !password) {
return ContentService.createTextOutput("Error: Missing username or password for registration.")
.setMimeType(ContentService.MimeType.TEXT);
}
// Check if username already exists
const lastRow = sheet.getLastRow();
if (lastRow > 1) {
const users = sheet.getRange(2, 1, lastRow - 1, 1).getValues();
const isDuplicate = users.some(row => row[0] === username);
if (isDuplicate) {
return ContentService.createTextOutput("Registration Failed: Username already exists.")
.setMimeType(ContentService.MimeType.TEXT);
}
}
// Append the new user data to the sheet
sheet.appendRow([username, password]);
return ContentService.createTextOutput("Registration Success")
.setMimeType(ContentService.MimeType.TEXT);
}
// Default response for other POST requests
return ContentService.createTextOutput("Error: Unknown action.")
.setMimeType(ContentService.MimeType.TEXT);
}


Please help. Thank you.
I am not up to the skill level of using Google scripts yet.
But if you wanted support lost passwords, wouldn't you need an email address to fall back on for a temporary login password, along with code to send the email and check if it gets used?
That's above my pay grade.
I note that you are saving passwords in plain text. You should, for data protection purposes, as a minimum, be hashing the password. There are several extensions available to do this.
I quite like this one:
or there is this:
If you wanted, you could hash both the user name and the password, then your spreadsheet could be set with Anyone with the link, and you could use gviz to read usernames and passwords, and then web component to update them.
Regarding your script, if you had it working before you added "forgot password", it should be easy enough to backtrack in order to find your error.
Yes, I am planning to send the new password in the user’s email. so, what I am thinking is to reset the password and send a new one in the email. have you done it before? or encountered that?
thank you, I will surely read those.
I am not familiar with gviz but don’t worry I’ll study them too.