Expo project works fine when using expo go app, but some functions do not work after building and installing the APK in my android phone

The app is integrated with Amazon cognito client for authentication, and has a few functions that get invoked onPress of a Pressable. I used this: “java -jar bundletool.jar build-apks –bundle=filename.aab –output=newfilename.apks –mode=universal –ks filetomykey –ks-alias _____…” to bundle my aab which I downloaded on expo.dev after building using “eas build –platform android” and I managed get and install apk in my andriod phone.

The problem is I have is that the Pressable and some functions do not work on my phone. I have function that perfoms some logic to retrieve some value from the tokenId used with cognito client. What the function does is: use SecureStore to get desired value from the tokenId and then returns an object. That same function is then used to Great user with their name which is retrieved from the tokenId. This functionality is not working on my phone (Oppo A15 Android v10) and the Pressable does not work also, but they were working when using the Expo Go app to test my app.

I am able sign in successfuly, so congito client function is working, but It seems like there is a problem when it comes to getting data from the tokenId, because now on my phone, The username of the logged in user does not display, it only displays the useState(“Name here”) value instead of the one set. Also I dont get any feedback when touching the Pressable on my phone screen. But all of this works with Expo goScreenshots of my code another screenshotanother screenshotanother screenshot

Here is the code that retrieves the token from SecureStore

import {jwtDecode} from 'jwt-decode'; // Ensure correct import
import * as SecureStore from 'expo-secure-store'; // Ensure you have expo-secure-store installed
import axios from 'axios';

interface User {
  id: number;
  username: string;
}

interface DecodedToken {
  given_name: string;
  family_name: string;
}

const apiUrl = 'http://1.1.1.1'; //dummy url

const getUserNameFromToken = async (): Promise<string | null> => {
  try {
    // Retrieve the stored token
    const token = await SecureStore.getItemAsync('idToken');
    console.log('Retrieved Token:', token);

    if (token) {
      const decodedToken = jwtDecode<DecodedToken>(token);
      console.log('Decoded Token:', decodedToken);

      if (decodedToken.given_name && decodedToken.family_name) {
        const firstName = decodedToken.given_name;
        const lastName = decodedToken.family_name;
        const userName = `${firstName} ${lastName}`;
        return userName;
      } else {
        console.error('Token does not contain given_name or family_name');
        return null;
      }
    } else {
      console.error('Token is undefined');
      return null;
    }
  } catch (error) {
    console.error('Failed to retrieve or decode token', error);
    return null;
  }
};

const fetchUsers = async (): Promise<User[]> => {
  try {
    const response = await axios.get(`${apiUrl}/users`);
    return response.data;
  } catch (error) {
    console.error('Failed to fetch users:', error);
    return [];
  }
};

export const getMatchedUser = async (): Promise<User | null> => {
  try {
    const userName = await getUserNameFromToken();
    if (!userName) {
      return null;
    }

    const users = await fetchUsers();
    const matchedUser = users.find((user) => user.username === userName);

    return matchedUser || null;
  } catch (error) {
    console.error('Error getting matched user:', error);
    return null;
  }
};

And here is my when user gets authorized, signsUp, and confirms account

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { CognitoIdentityProviderClient, InitiateAuthCommand, SignUpCommand, ConfirmSignUpCommand } from "@aws-sdk/client-cognito-identity-provider";
import config from "../../config.json"
import * as SecureStore from 'expo-secure-store';
import 'react-native-get-random-values';
import 'react-native-url-polyfill/auto';
import { ReadableStream } from "web-streams-polyfill";
globalThis.ReadableStream = ReadableStream;
import { v4 as uuidv4 } from "uuid";

const readable = new ReadableStream();

export const cognitoClient = new CognitoIdentityProviderClient({
  region: config.region,
});

export const signIn = async (username: string, password: string) => {
  const params = {
    AuthFlow: "USER_PASSWORD_AUTH",
    ClientId: config.clientId,
    AuthParameters: {
      USERNAME: username,
      PASSWORD: password,
    },
  };
  try {
    const command = new InitiateAuthCommand(params);
    const { AuthenticationResult } = await cognitoClient.send(command);
    if (AuthenticationResult) {
        await SecureStore.setItemAsync("idToken", AuthenticationResult.IdToken || '');
        await SecureStore.setItemAsync("accessToken", AuthenticationResult.AccessToken || '');
        await SecureStore.setItemAsync("refreshToken", AuthenticationResult.RefreshToken || '');
      return AuthenticationResult;
    }
  } catch (error) {
    console.error("Error signing in: ", error);
    throw error;
  }
};

export const signUp = async (username: string, fName: string, lName: string, email: string, password: string) => {
  const params = {
    ClientId: config.clientId,
    Username: username,
    Password: password,
    UserAttributes: [
      {
        Name: "email",
        Value: email,
      },
      {
        Name: "given_name",
        Value: fName,
      },{
        Name: "family_name",
        Value: lName,
      },
    ],
  };
  try {
    console.log("Params: ",params)
    const command = new SignUpCommand(params);
    console.log("Command: ",command)
    const response = await cognitoClient.send(command);
    console.log("Sign up success: ", response);
    return response;
  } catch (error) {
    console.error("Error signing up: ", error);
    throw error;
  }
};

export const confirmSignUp = async (username: string, code: string) => {
  const params = {
    ClientId: config.clientId,
    Username: username,
    ConfirmationCode: code,
  };
  try {
    const command = new ConfirmSignUpCommand(params);
    await cognitoClient.send(command);
    console.log("User confirmed successfully");
    return true;
  } catch (error) {
    console.error("Error confirming sign up: ", error);
    throw error;
  }
};

This is when I do Post using Axios (there are three other similar functions, difference is endoints and alert messages):

import axios from 'axios';

const apiUrl = 'http://1.1.1.1:4000/check-in-morning';

const checkInMorning = async (userId) => {
  try {
    const response = await axios.post(apiUrl, {
      data: { userId: userId }
    }, {
      headers: {
        'accept': '*/*',
        'Content-Type': 'application/json'
      }
    });
    console.log('Response:', response.data);
    return response.data;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
};

export default checkInMorning;

SignUp page:

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { CognitoIdentityProviderClient, InitiateAuthCommand, SignUpCommand, ConfirmSignUpCommand } from "@aws-sdk/client-cognito-identity-provider";
import config from "../../config.json"
import * as SecureStore from 'expo-secure-store';
import 'react-native-get-random-values';
import 'react-native-url-polyfill/auto';
import { ReadableStream } from "web-streams-polyfill";
globalThis.ReadableStream = ReadableStream;
import { v4 as uuidv4 } from "uuid";

const readable = new ReadableStream();

export const cognitoClient = new CognitoIdentityProviderClient({
  region: config.region,
});

export const signIn = async (username: string, password: string) => {
  const params = {
    AuthFlow: "USER_PASSWORD_AUTH",
    ClientId: config.clientId,
    AuthParameters: {
      USERNAME: username,
      PASSWORD: password,
    },
  };
  try {
    const command = new InitiateAuthCommand(params);
    const { AuthenticationResult } = await cognitoClient.send(command);
    if (AuthenticationResult) {
        await SecureStore.setItemAsync("idToken", AuthenticationResult.IdToken || '');
        await SecureStore.setItemAsync("accessToken", AuthenticationResult.AccessToken || '');
        await SecureStore.setItemAsync("refreshToken", AuthenticationResult.RefreshToken || '');
      return AuthenticationResult;
    }
  } catch (error) {
    console.error("Error signing in: ", error);
    throw error;
  }
};

export const signUp = async (username: string, fName: string, lName: string, email: string, password: string) => {
  const params = {
    ClientId: config.clientId,
    Username: username,
    Password: password,
    UserAttributes: [
      {
        Name: "email",
        Value: email,
      },
      {
        Name: "given_name",
        Value: fName,
      },{
        Name: "family_name",
        Value: lName,
      },
    ],
  };
  try {
    console.log("Params: ",params)
    const command = new SignUpCommand(params);
    console.log("Command: ",command)
    const response = await cognitoClient.send(command);
    console.log("Sign up success: ", response);
    return response;
  } catch (error) {
    console.error("Error signing up: ", error);
    throw error;
  }
};

export const confirmSignUp = async (username: string, code: string) => {
  const params = {
    ClientId: config.clientId,
    Username: username,
    ConfirmationCode: code,
  };
  try {
    const command = new ConfirmSignUpCommand(params);
    await cognitoClient.send(command);
    console.log("User confirmed successfully");
    return true;
  } catch (error) {
    console.error("Error confirming sign up: ", error);
    throw error;
  }
};

SignIn page:

import React from "react";
import { View, Text, Image, ScrollView, Alert } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { SafeAreaView } from "react-native-safe-area-context";
import { useForm, Controller } from "react-hook-form";
import { images } from "../../constants";
import FormField from "../../components/FormField";
import CustomButton from "../../components/CustomButton";
import { Link, router } from "expo-router";
import { signIn } from "../services/authService";

import * as SecureStore from "expo-secure-store";
import "react-native-get-random-values";
import { v4 as uuidv4 } from "uuid";

const SignIn = () => {
  const {
    control,
    handleSubmit,
    formState: { errors },
  } = useForm();


  const onSubmit = async (data) => {
    try {
      const session = await signIn(data.username, data.password);
      console.log("Sign in successful", session);

      if (session && session.AccessToken) {
        
        await SecureStore.setItemAsync("accessToken", session.AccessToken);

        // Retrieve the token to check if it's stored correctly
        const storedToken = await SecureStore.getItemAsync("accessToken");
        if (storedToken) {
          router.push("../(tabs)/home");
        } else {
          console.error("Session token was not set properly.");
        }
      } else {
        console.error("SignIn session or AccessToken is undefined.");
      }
    } catch (error) {
      console.error("Sign in failed:", error);
      alert("Sign in failed. Please try again.");
    }
  };

  return (
    <GestureHandlerRootView>
      <SafeAreaView className="bg-primary h-full">
        <View className="w-full justify-center px-4">
        <Text className="text-white text-2xl mt-10 mb-10 font-psemibold">
              Log in to{" "}
              <Text className="text-secondary-200">app name</Text>
            </Text>
        </View>
      
        <ScrollView contentContainerStyle={{ height: "90%" }}>
          <View className="w-full justify-center min-h-[8vh] px-4 my-6">
           
            <Controller
              control={control}
              render={({ field }) => (
                <FormField
                  title="Username"
                  placeholder="Enter your username"
                  value={field.value}
                  handleChangeText={field.onChange}
                  fieldName="username"
                  otherStyles="mt-7"
                  errorMessage={errors.username && errors.username.message} // Pass error message
                />
              )}
              name="username"
              rules={{
                required: "Username is required",
                pattern: {
                  value: /^[A-Z][a-z]+_[A-Z][a-z]+$/,
                  message:
                    "Username must be in the format 'Firstname_Lastname'",
                },
              }}
            />

            <Controller
              className="mt-7"
              control={control}
              render={({ field }) => (
                <FormField
                  title="Password"
                  placeholder="Enter your password"
                  value={field.value}
                  handleChangeText={field.onChange}
                  otherStyles="mt-7"
                  // secureTextEntry={title === 'Password' && !showPassword}
                  errorMessage={errors.password && errors.password.message} // Pass error message
                />
              )}
              name="password"
              rules={{
                required: "Password is required",
                minLength: {
                  value: 8,
                  message: "Password must be at least 8 characters long",
                },
                pattern: {
                  value: /^(?=.*d)(?=.*[a-zA-Z])(?=.*[W_]).{8,}$/,
                  message:
                    "Password must contain at least one letter, one number, and one special character",
                },
              }}
            />

            <CustomButton
              title="Sign In"
              handlePress={handleSubmit(onSubmit)}
              containerStyles={"mt-7"}
            />

            <View className="justify-center pt-5 flex-row gap-2">
              <Text className="text-lg text-gray-100 ">
                Don't have account?
              </Text>
              <Link
                href="/sign-up"
                className="text-lg text-secondary font-psemibold"
              >
                Sign Up
              </Link>
            </View>
          </View>
        </ScrollView>
      </SafeAreaView>
    </GestureHandlerRootView>
  );
};

export default SignIn;

Confirm signUp:

import React from "react";
import { View, Text, Image, ScrollView, Alert } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { SafeAreaView } from "react-native-safe-area-context";
import { useForm, Controller } from "react-hook-form";

import { images } from "../../constants";
import FormField from "../../components/FormField";
import CustomButton from "../../components/CustomButton";
import { Link, router } from "expo-router";
import { confirmSignUp } from "../services/authService";

const ConfirmPage = () => {
  const usernamePattern = /^[A-Z][a-z]+_[A-Z][a-z]+$/;
  const {
    control,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = async (data) => {
    if (!usernamePattern.test(data.username)) {
      alert("Please enter your first name and last name separated by an underscore (e.g., Joe_Doe)");
      return;
    }
    try {
      await confirmSignUp(data.username, data.code);
      alert(`Account confirmed successfully!nSign in on next page.`);
      router.push('./sign-in');
    } catch (error) {
      alert(`Failed to confirm account: ${error} Email:${ String(data.email)} Code:${String(data.code)}`);
    }
  };


  return (
    <GestureHandlerRootView>
      <SafeAreaView className="bg-primary h-full">
        <ScrollView>
          <View className="w-full justify-center min-h-[85vh] px-4 my-6">
            
            <Text className="text-white text-2xl font-psemibold">
              Account verification
            </Text>

            <Controller
              control={control}
              render={({ field }) => (
                <FormField
                  title="Username"
                  placeholder="Enter your username"
                  value={field.value}
                  handleChangeText={field.onChange}
                  fieldName="username"
                  otherStyles="mt-7"
                  errorMessage={errors.username && errors.username.message} // Pass error message
                />
              )}
              name="username"
              rules={{
                required: "Username is required",
                pattern: {
                  value: /^[A-Z][a-z]+_[A-Z][a-z]+$/,
                  message:
                    "Username must be in the format 'Firstname_Lastname'",
                },
              }}
            />

            <Controller
              className="mt-7"
              control={control}
              render={({ field }) => (
                <FormField
                  title="Code"
                  placeholder="Enter your code"
                  value={field.value}
                  handleChangeText={field.onChange}
                  otherStyles="mt-7"
                  errorMessage={errors.code && errors.code.message}
                />
              )}
              name="code"
              rules={{
                required: "Code is required",
                maxLength: {
                  value: 10,
                  message: "Code must be no more than 10 digits long",
                },
                pattern: {
                  value: /^d{1,10}$/,
                  message: "Code must be a valid number up to 10 digits",
                },
              }}
            />

            <CustomButton
              title="Confirm"
              handlePress={handleSubmit(onSubmit)}
              containerStyles={"mt-7"}
            />
          </View>
        </ScrollView>
      </SafeAreaView>
    </GestureHandlerRootView>
  );
};

export default ConfirmPage;

Home page (where I cannot press Pressable, or it’s pressable but the onPress functions do not get invoked):

import React, { useState, useEffect } from "react";
import { Text, View, Pressable } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { getMatchedUser } from "../services/authUtils";
import checkInMorning from '../activities/morning'
import checkInLunch from '../activities/backLunch'
import checkOutAfternoon from '../activities/afternoon'
import checkOutLunch from "../activities/outLunch";

export default function Home() {
  const [userName, setUserName] = useState("Username Here");
  const [matchedUser, setMatchedUser] = useState(null);



  useEffect(() => {
    const fetchMatchedUser = async () => {
      const user = await getMatchedUser();
      if (user) {
        setUserName(user.username);
        setMatchedUser(user);
      } else {
        setUserName("No matching user found");
        setMatchedUser(null);
      }
    };

    fetchMatchedUser();
  }, []);

  const handleCheckInMorning = async () => {
    try {
      const result = await checkInMorning(matchedUser.id);
      console.log('Check-in successful:', result);
      alert("Check-in Successful");
    } catch (error) {
      console.error('Check-in failed:', error);
    }
  };

  const handleCheckInLunch = async () => {
    try {
      const result = await checkInLunch(matchedUser.id);
      console.log('Check-in successful:', result);
      alert("Check-in Successful");
    } catch (error) {
      console.error('Check-in failed:', error);
    }
  };

  const handleCheckOutAfternoon = async () => {
    try {
      const result = await checkOutAfternoon(matchedUser.id);
      console.log('Check-out successful:', result);
      alert("Check-Out Successful");
    } catch (error) {
      console.error('Check-in failed:', error);
    }
  };

  const handleCheckOutLunch = async () => {
    try {
      const result = await checkOutLunch(matchedUser.id);
      console.log('Check-out successful:', result);
      alert("Check-Out Successful");
    } catch (error) {
      console.error('Check-in failed:', error);
    }
  };

  return (
    <GestureHandlerRootView>
      <SafeAreaView className="bg-[#d9d9d9] h-full py-10">
        <View className="justify-center items-center">
          <Text>Hi {userName}</Text>
          {matchedUser ? (
            <Text>
              Welcome, {matchedUser.username} (ID: {matchedUser.id})
            </Text>
          ) : (
            <Text>No matching user found</Text>
          )}

          <Pressable className="w-[200] h-20 m-10 bg-secondary justify-center items-center " onPressOut={handleCheckInMorning}>
            <Text className="text-white font-psemibold">Check In morning</Text>
          </Pressable>

          <Pressable className="w-[200] h-20 m-10 bg-secondary justify-center items-center " onPressOut={handleCheckInLunch}>
            <Text className="text-white font-psemibold">Check In back from lunch</Text>
          </Pressable>

          <Pressable className="w-[200] h-20 m-10 bg-secondary justify-center items-center " onPressOut={handleCheckOutLunch}>
            <Text className="text-white font-psemibold">Check Out for lunch</Text>
          </Pressable>

          <Pressable className="w-[200] h-20 m-10 bg-secondary justify-center items-center " onPressOut={handleCheckOutAfternoon}>
            <Text className="text-white font-psemibold">Check Out afternoon</Text>
          </Pressable>

        </View>
      </SafeAreaView>
    </GestureHandlerRootView>
  );
}

My package file:

{
  "name": "app-name",
  "version": "1.0.0",
  "main": "expo-router/entry",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@aws-amplify/backend": "^1.0.1",
    "@aws-amplify/backend-cli": "^1.0.2",
    "@aws-amplify/react-native": "^1.1.0",
    "@aws-amplify/ui-react-native": "^2.2.0",
    "@aws-sdk/client-cognito-identity-provider": "^3.533.0",
    "@babel/plugin-transform-async-generator-functions": "^7.24.3",
    "@babel/plugin-transform-class-properties": "^7.24.1",
    "@babel/plugin-transform-logical-assignment-operators": "^7.24.1",
    "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1",
    "@babel/plugin-transform-numeric-separator": "^7.24.1",
    "@babel/plugin-transform-object-rest-spread": "^7.24.5",
    "@babel/plugin-transform-optional-chaining": "^7.24.5",
    "@react-native-async-storage/async-storage": "^1.23.1",
    "@react-native-community/geolocation": "^3.2.1",
    "@react-native-community/netinfo": "^11.3.1",
    "@types/react": "~18.2.45",
    "aws-amplify": "^6.3.0",
    "aws-cdk": "^2.141.0",
    "aws-cdk-lib": "^2.141.0",
    "axios": "^1.6.8",
    "constructs": "^10.3.0",
    "core-js": "^3.37.0",
    "esbuild": "^0.21.2",
    "expo": "~51.0.2",
    "expo-av": "~14.0.4",
    "expo-constants": "~16.0.1",
    "expo-device": "~6.0.2",
    "expo-document-picker": "~12.0.1",
    "expo-font": "~12.0.5",
    "expo-linking": "~6.3.1",
    "expo-location": "~17.0.1",
    "expo-router": "^3.5.11",
    "expo-secure-store": "~13.0.1",
    "expo-status-bar": "~1.12.1",
    "install": "^0.13.0",
    "jwt-decode": "^4.0.0",
    "nativewind": "^2.0.11",
    "react": "18.2.0",
    "react-hook-form": "^7.51.4",
    "react-native": "^0.74.1",
    "react-native-animatable": "^1.4.0",
    "react-native-appwrite": "^0.2.2",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-get-random-values": "^1.11.0",
    "react-native-modalize": "^2.1.1",
    "react-native-reanimated": "~3.10.1",
    "react-native-safe-area-context": "^4.10.1",
    "react-native-screens": "^3.31.1",
    "react-native-url-polyfill": "^2.0.0",
    "react-native-webview": "13.8.6",
    "tsx": "^4.10.1",
    "typescript": "~5.3.3",
    "uuid": "^9.0.1",
    "web-streams-polyfill": "^4.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.24.3",
    "tailwindcss": "3.3.2"
  },
  "private": true
}

App.json:

{
  "expo": {
    "name": "app_name",
    "slug": "snug_name",
    "version": "1.0.1",
    "orientation": "portrait",
    "icon": "./assets/icon2.png",
    "scheme": "myapp",
    "userInterfaceStyle": "automatic",
    "splash": {
      "image": "./assets/splash2.1.png",
      "resizeMode": "contain",
      "backgroundColor": "#276966"
    },
    "ios": {
      "supportsTablet": true,
      "config": {
        "usesNonExemptEncryption": false
      }
    },
    "android": {
      "package": "com.package.name",
      "versionCode": 2,
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive_icon.png",
        "backgroundColor": "#ffffff"
      },
      "permissions": [
        "android.permission.ACCESS_COARSE_LOCATION",
        "android.permission.ACCESS_FINE_LOCATION"
      ]
    },
    "web": {
      "bundler": "metro",
      "output": "static",
      "favicon": "./assets/images/favicon.png"
    },
    "plugins": [
      "expo-router",
      [
        "expo-secure-store",
        {
          "faceIDPermission": "Allow $(PRODUCT_NAME) to access your Face ID biometric data."
        }
      ],
      [
        "expo-location",
        {
          "locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location."
        }
      ]
    ],
    "experiments": {
      "typedRoutes": true
    },
    "extra": {
      "router": {
        "origin": false
      },
      "eas": {
        "projectId": "myprojectIdhere"
      }
    }
  }
}

All of these work when I run my app on Expo Go but I face some problems on the apk

I tried running app on Expo Go again to confirm if built the updated version. And Everything works as expected on the Expo Go app, but on not with the installed apk

SignIn page is similar to signUp

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật