Firebase Realtime Database: Player 2 unable to interact with game in Unity multiplayer setup

I’m developing a multiplayer game in Unity using Firebase Realtime Database for data synchronization between players. In my setup, both players interact with the game through the same GameController script instance.

The issue I’m encountering is that player 2 is unable to interact with the game or see updates to game state, while player 1 (the host) can interact with the game as expected. Here’s a summary of the problem:

Setup: I have a GameController script that handles game logic and data management for both players. Player 1 creates the game room, and player 2 joins the room.
Data Synchronization: The GameController script communicates with Firebase Realtime Database to synchronize game state between players, including player scores, current turn, selected topic, etc.
Problem: After player 2 joins the game, they are not able to submit answers, see the selected topic, or receive updates to game state. It seems like the data retrieval and update methods are not being executed properly for player 2.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>public class GameController : MonoBehaviour
{
public static GameController instance;
public FirebaseFunctionsHandler firebaseHandler;
public DatabaseReference databaseReference;
private FirebaseFunctions functions;
public TextMeshProUGUI timerText;
public TextMeshProUGUI topicText;
public TMP_InputField playerInput;
public TextMeshProUGUI resultText;
public TextMeshProUGUI player1ScoreText;
public TextMeshProUGUI player2ScoreText;
public TextMeshProUGUI player1nameText;
public TextMeshProUGUI player2nameText;
public TextMeshProUGUI invalidWordText;
public TextMeshProUGUI TurnLabel;
public Button submitButton;
public AudioSource correctSound;
public AudioSource incorrectSound;
private string selectedTopic;
private List<string> validWords;
private List<string> usedWords = new List<string>();
private int player1Score = 0;
private int player2Score = 0;
bool wordExists;
private bool gameActive = true;
private bool player1Turn = true; // Track whose turn it is
private float originalTimer = 10f; // Store the original timer value
private float timer; // Timer variable
private int player1Coins = 0;
private int player2Coins = 0;
public GameOverController gameOverController;
private MatchmakingManager matchmakingManager;
private TopicManager.TopicTree topicTree;
void Start()
{
topicTree = TopicManager.Instance.topicTree;
TopicManager.Instance.InitializeTopics();
databaseReference = FirebaseDatabase.DefaultInstance.RootReference;
functions = FirebaseFunctions.DefaultInstance;
matchmakingManager = FindObjectOfType<MatchmakingManager>();
if (matchmakingManager == null)
{
Debug.LogError("MatchmakingManager not found in the scene.");
return;
}
submitButton.onClick.AddListener(submitAnswer3);
StartCoroutine(PlayGame());
FetchAndDisplayUsername();
FetchAndDisplayPlayer2Name();
}
IEnumerator PlayGame()
{
FetchAndDisplaySelectedTopic(RoomManager.CurrentRoomId);
while (gameActive)
{
timer = originalTimer; // Reset the timer
UpdateResultText(); // Update result text to indicate the current player's turn
yield return StartCoroutine(PlayerTurn());
if (!gameActive) break;
}
DisplayScores();
} public async void submitAnswer3()
{
string currentInput = playerInput.text.ToLower();
currentInput = NormalizeWord(currentInput);
Debug.Log("Current Input: " + currentInput);
Debug.Log("Selected Topic: " + selectedTopicManager.selectedTopic);
wordExists = await CallCloudFunction(selectedTopicManager.selectedTopic, currentInput);
if (wordExists)
{
// The word exists in the database
Debug.Log("Word exists in the database from word exist .");
UpdateScore();
resultText.text = "Correct!";
SwitchTurn();
timer = originalTimer;
correctSound.Play();
UpdateUsedWordsInDatabase(RoomManager.CurrentRoomId);
}
else
{
// The word does not exist in the database
Debug.LogWarning("Word does not exist in the database from word exist.");
invalidWordText.text = ArabicFixer.Fix("خطا,كلمة لا تتعلق بالموضوع");
invalidWordText.gameObject.SetActive(true);
gameActive = false;
timer = 0f; // Set the timer to zero when a wrong answer is submitted
incorrectSound.Play();
DetermineWinner();
}
DisplayScores();
}
async void FetchAndDisplayUsername()
{
string userId = FirebaseAuth.DefaultInstance.CurrentUser.UserId;
DataSnapshot snapshot = await databaseReference.Child("users").Child(userId).GetValueAsync();
if (snapshot.Exists)
{
UserProfile userProfile = JsonUtility.FromJson<UserProfile>(snapshot.GetRawJsonValue());
string username = userProfile.username;
// Display the username in the UI
player1nameText.text = username ;
}
else
{
Debug.LogError("User profile not found in the database.");
}
}
async void FetchAndDisplayPlayer2Name()
{
// Fetch the player 2 ID from the gameRooms node
DataSnapshot roomSnapshot = await databaseReference.Child("gameRooms").Child(RoomManager.CurrentRoomId).Child("players").GetValueAsync();
if (roomSnapshot.Exists && roomSnapshot.HasChild("player2"))
{
string player2Id = roomSnapshot.Child("player2").Value.ToString();
// Fetch the player 2 name from the database
DataSnapshot playerSnapshot = await databaseReference.Child("users").Child(player2Id).GetValueAsync();
if (playerSnapshot.Exists)
{
UserProfile userProfile = JsonUtility.FromJson<UserProfile>(playerSnapshot.GetRawJsonValue());
string player2Name = userProfile.username;
player2nameText.text = player2Name;
// Display the player 2 name in the UI or wherever needed
Debug.Log("Player 2 id: " + player2Id);
}
else
{
Debug.LogError("Player 2 profile not found in the database.");
}
}
else
{
Debug.LogError("Player 2 ID not found in the gameRooms node.");
}
}
</code>
<code>public class GameController : MonoBehaviour { public static GameController instance; public FirebaseFunctionsHandler firebaseHandler; public DatabaseReference databaseReference; private FirebaseFunctions functions; public TextMeshProUGUI timerText; public TextMeshProUGUI topicText; public TMP_InputField playerInput; public TextMeshProUGUI resultText; public TextMeshProUGUI player1ScoreText; public TextMeshProUGUI player2ScoreText; public TextMeshProUGUI player1nameText; public TextMeshProUGUI player2nameText; public TextMeshProUGUI invalidWordText; public TextMeshProUGUI TurnLabel; public Button submitButton; public AudioSource correctSound; public AudioSource incorrectSound; private string selectedTopic; private List<string> validWords; private List<string> usedWords = new List<string>(); private int player1Score = 0; private int player2Score = 0; bool wordExists; private bool gameActive = true; private bool player1Turn = true; // Track whose turn it is private float originalTimer = 10f; // Store the original timer value private float timer; // Timer variable private int player1Coins = 0; private int player2Coins = 0; public GameOverController gameOverController; private MatchmakingManager matchmakingManager; private TopicManager.TopicTree topicTree; void Start() { topicTree = TopicManager.Instance.topicTree; TopicManager.Instance.InitializeTopics(); databaseReference = FirebaseDatabase.DefaultInstance.RootReference; functions = FirebaseFunctions.DefaultInstance; matchmakingManager = FindObjectOfType<MatchmakingManager>(); if (matchmakingManager == null) { Debug.LogError("MatchmakingManager not found in the scene."); return; } submitButton.onClick.AddListener(submitAnswer3); StartCoroutine(PlayGame()); FetchAndDisplayUsername(); FetchAndDisplayPlayer2Name(); } IEnumerator PlayGame() { FetchAndDisplaySelectedTopic(RoomManager.CurrentRoomId); while (gameActive) { timer = originalTimer; // Reset the timer UpdateResultText(); // Update result text to indicate the current player's turn yield return StartCoroutine(PlayerTurn()); if (!gameActive) break; } DisplayScores(); } public async void submitAnswer3() { string currentInput = playerInput.text.ToLower(); currentInput = NormalizeWord(currentInput); Debug.Log("Current Input: " + currentInput); Debug.Log("Selected Topic: " + selectedTopicManager.selectedTopic); wordExists = await CallCloudFunction(selectedTopicManager.selectedTopic, currentInput); if (wordExists) { // The word exists in the database Debug.Log("Word exists in the database from word exist ."); UpdateScore(); resultText.text = "Correct!"; SwitchTurn(); timer = originalTimer; correctSound.Play(); UpdateUsedWordsInDatabase(RoomManager.CurrentRoomId); } else { // The word does not exist in the database Debug.LogWarning("Word does not exist in the database from word exist."); invalidWordText.text = ArabicFixer.Fix("خطا,كلمة لا تتعلق بالموضوع"); invalidWordText.gameObject.SetActive(true); gameActive = false; timer = 0f; // Set the timer to zero when a wrong answer is submitted incorrectSound.Play(); DetermineWinner(); } DisplayScores(); } async void FetchAndDisplayUsername() { string userId = FirebaseAuth.DefaultInstance.CurrentUser.UserId; DataSnapshot snapshot = await databaseReference.Child("users").Child(userId).GetValueAsync(); if (snapshot.Exists) { UserProfile userProfile = JsonUtility.FromJson<UserProfile>(snapshot.GetRawJsonValue()); string username = userProfile.username; // Display the username in the UI player1nameText.text = username ; } else { Debug.LogError("User profile not found in the database."); } } async void FetchAndDisplayPlayer2Name() { // Fetch the player 2 ID from the gameRooms node DataSnapshot roomSnapshot = await databaseReference.Child("gameRooms").Child(RoomManager.CurrentRoomId).Child("players").GetValueAsync(); if (roomSnapshot.Exists && roomSnapshot.HasChild("player2")) { string player2Id = roomSnapshot.Child("player2").Value.ToString(); // Fetch the player 2 name from the database DataSnapshot playerSnapshot = await databaseReference.Child("users").Child(player2Id).GetValueAsync(); if (playerSnapshot.Exists) { UserProfile userProfile = JsonUtility.FromJson<UserProfile>(playerSnapshot.GetRawJsonValue()); string player2Name = userProfile.username; player2nameText.text = player2Name; // Display the player 2 name in the UI or wherever needed Debug.Log("Player 2 id: " + player2Id); } else { Debug.LogError("Player 2 profile not found in the database."); } } else { Debug.LogError("Player 2 ID not found in the gameRooms node."); } } </code>
public class GameController : MonoBehaviour
{
    
    public static GameController instance;
    public FirebaseFunctionsHandler firebaseHandler;

    public DatabaseReference databaseReference;
    private FirebaseFunctions functions;

    public TextMeshProUGUI timerText;
    public TextMeshProUGUI topicText;
    public TMP_InputField playerInput;
    public TextMeshProUGUI resultText;
    public TextMeshProUGUI player1ScoreText;
    public TextMeshProUGUI player2ScoreText;
    public TextMeshProUGUI player1nameText;
    public TextMeshProUGUI player2nameText;
    public TextMeshProUGUI invalidWordText;
    public TextMeshProUGUI TurnLabel;
    public Button submitButton;

    public AudioSource correctSound;
    public AudioSource incorrectSound;

    private string selectedTopic;
    private List<string> validWords;
    private List<string> usedWords = new List<string>();
    private int player1Score = 0;
    private int player2Score = 0;
    bool wordExists;

    private bool gameActive = true;
    private bool player1Turn = true; // Track whose turn it is
    private float originalTimer = 10f; // Store the original timer value
    private float timer; // Timer variable

    private int player1Coins = 0;
    private int player2Coins = 0;
    public GameOverController gameOverController;

    private MatchmakingManager matchmakingManager;

    private TopicManager.TopicTree topicTree;
    
    void Start()
    {
        

        topicTree = TopicManager.Instance.topicTree;
        TopicManager.Instance.InitializeTopics();

        databaseReference = FirebaseDatabase.DefaultInstance.RootReference;
        functions = FirebaseFunctions.DefaultInstance;
        matchmakingManager = FindObjectOfType<MatchmakingManager>();
        if (matchmakingManager == null)
        {
            Debug.LogError("MatchmakingManager not found in the scene.");
            return;
        }
       
        submitButton.onClick.AddListener(submitAnswer3);
        StartCoroutine(PlayGame());

      

        FetchAndDisplayUsername();
       FetchAndDisplayPlayer2Name();
       
        
        
    }


    IEnumerator PlayGame()
    {
        
    
        FetchAndDisplaySelectedTopic(RoomManager.CurrentRoomId);
       

        while (gameActive)
        {
            timer = originalTimer; // Reset the timer
            UpdateResultText(); // Update result text to indicate the current player's turn
            
            yield return StartCoroutine(PlayerTurn());
            if (!gameActive) break;
        }

        DisplayScores();
        
    } public async void submitAnswer3()
  {

      string currentInput = playerInput.text.ToLower();
      currentInput = NormalizeWord(currentInput);
      Debug.Log("Current Input: " + currentInput);
      Debug.Log("Selected Topic: " + selectedTopicManager.selectedTopic);
     wordExists = await CallCloudFunction(selectedTopicManager.selectedTopic, currentInput);
      if (wordExists)
      {
          // The word exists in the database
          Debug.Log("Word exists in the database from word exist .");
          UpdateScore();
          resultText.text = "Correct!";
          SwitchTurn();
          timer = originalTimer;
          correctSound.Play();
          UpdateUsedWordsInDatabase(RoomManager.CurrentRoomId);
      }
      else
      {
          // The word does not exist in the database
          Debug.LogWarning("Word does not exist in the database from word exist.");
          invalidWordText.text = ArabicFixer.Fix("خطا,كلمة لا تتعلق بالموضوع");
          invalidWordText.gameObject.SetActive(true);
          gameActive = false;
          timer = 0f; // Set the timer to zero when a wrong answer is submitted
          incorrectSound.Play();
          DetermineWinner();
      }
      DisplayScores();
  }
    async void FetchAndDisplayUsername()
{
    string userId = FirebaseAuth.DefaultInstance.CurrentUser.UserId;
    DataSnapshot snapshot = await databaseReference.Child("users").Child(userId).GetValueAsync();

    if (snapshot.Exists)
    {
        UserProfile userProfile = JsonUtility.FromJson<UserProfile>(snapshot.GetRawJsonValue());
        string username = userProfile.username;

        // Display the username in the UI
      player1nameText.text =   username ;
    }
    else
    {
        Debug.LogError("User profile not found in the database.");
    }
}

async void FetchAndDisplayPlayer2Name()
{
    // Fetch the player 2 ID from the gameRooms node
    DataSnapshot roomSnapshot = await databaseReference.Child("gameRooms").Child(RoomManager.CurrentRoomId).Child("players").GetValueAsync();
    if (roomSnapshot.Exists && roomSnapshot.HasChild("player2"))
    {
        string player2Id = roomSnapshot.Child("player2").Value.ToString();

        // Fetch the player 2 name from the database
        DataSnapshot playerSnapshot = await databaseReference.Child("users").Child(player2Id).GetValueAsync();

        if (playerSnapshot.Exists)
        {
            UserProfile userProfile = JsonUtility.FromJson<UserProfile>(playerSnapshot.GetRawJsonValue());
            string player2Name = userProfile.username;

            player2nameText.text = player2Name;
            // Display the player 2 name in the UI or wherever needed
            Debug.Log("Player 2 id: " + player2Id);
        }
        else
        {
            Debug.LogError("Player 2 profile not found in the database.");
        }
    }
    else
    {
        Debug.LogError("Player 2 ID not found in the gameRooms node.");
    }
}

I’ve checked the following:

Data retrieval methods (FetchAndDisplayPlayer2Name, FetchAndDisplaySelectedTopic, etc.) are being called and executed properly.
Data update methods (UpdateUsedWordsInDatabase, UpdateScoreInDatabase, etc.) are correctly updating the data in the database for both players.
There are no access control restrictions or errors in the database rules that might be causing the issue.
I’m looking for suggestions on how to debug and fix this issue. Any insights or tips on ensuring proper data synchronization between players in a Firebase Realtime Database setup would be greatly appreciated.

Thank you in advance for your help!

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