Skip to content

Conversation

@aalej
Copy link
Contributor

@aalej aalej commented Nov 24, 2025

Description

It seems like when adding a package via the Xcode UI https://firebase.google.com/docs/ios/installation-methods#via-xcode, the packages are listed in a different file, project.pbxproj.

potential fix for #9495 if they are using the Xcode UI to add packages

Scenarios Tested

Ran the ff script on an iOS project that has crashlytics

#!/usr/bin/env python3
import subprocess, json, time

process = subprocess.Popen(
    ['firebase', 'mcp', '--dir', '/PATH/iosProject/testApp'],
    stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, bufsize=1
)

# Step 1: Initialize - WORKS (responds immediately)
process.stdin.write(json.dumps({
    "jsonrpc": "2.0", "id": 1, "method": "initialize",
    "params": {"protocolVersion": "2024-11-05", "capabilities": {},
               "clientInfo": {"name": "test", "version": "1.0"}}
}) + '\n')
process.stdin.flush()
response = process.stdout.readline()
print(f"✓ Initialize responded: {response[:100]}")

# Step 2: Initialized notification
process.stdin.write(json.dumps({
    "jsonrpc": "2.0", "method": "notifications/initialized", "params": {}
}) + '\n')
process.stdin.flush()
time.sleep(0.5)

# Step 3: tools/list
process.stdin.write(json.dumps({
    "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}
}) + '\n')
process.stdin.flush()
response = process.stdout.readline()
tools_list = json.loads(response)['result']['tools']
print(f"✓ tools responded: {response}")
print(f"total tools: {len(tools_list)}")


for tool in tools_list:
    print(tool['name'])
    
time.sleep(10)
process.terminate()

Sample Commands

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @aalej, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves an issue where the Mobile Client Platform (MCP) server failed to detect Crashlytics integration in iOS applications that added Firebase packages through the Xcode user interface. The previous detection mechanism did not account for package references stored within the project.pbxproj file, leading to incorrect assessments of Crashlytics availability. By extending the scanning logic to include this file, the change ensures accurate Crashlytics detection for a broader range of iOS project configurations, thereby improving the reliability of Firebase tooling.

Highlights

  • Crashlytics Detection Fix: The MCP server now correctly identifies Crashlytics usage in iOS projects that integrate Firebase via the Xcode UI, where package information is stored in the project.pbxproj file.
  • Improved iOS Project Scanning: The iosAppUsesCrashlytics utility function has been enhanced to scan project.pbxproj files for Crashlytics references, ensuring comprehensive detection.
  • New Test Case: A new test case was added to validate the correct detection of Crashlytics in iOS projects utilizing project.pbxproj.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes an issue where Crashlytics was not detected in iOS projects that use project.pbxproj for package management. The change adds logic to scan project.pbxproj files for Crashlytics dependencies, and includes a new test case to verify this. The change is correct, but I've identified an opportunity to refactor the iosAppUsesCrashlytics function to reduce code duplication and improve performance. My feedback includes a suggestion for this refactoring.

Comment on lines +83 to +89
const xcodeProjectFiles = await detectFiles(appPath, "project.pbxproj");
for (const file of xcodeProjectFiles) {
const content = await fs.readFile(path.join(appPath, file), "utf8");
if (content.includes("Crashlytics")) {
return true;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of code is nearly identical to the three preceding blocks that check for other file types. This code repetition makes the function less maintainable and can be inefficient as it checks for each file type sequentially.

To improve this, you could refactor the logic to avoid code duplication and improve performance by reading files in parallel. This would make iosAppUsesCrashlytics more concise, performant, and easier to extend.

For example, you could refactor the function to something like this:

async function iosAppUsesCrashlytics(appPath: string): Promise<boolean> {
  const filePatterns = ["Podfile", "Package.swift", "Cartfile*", "project.pbxproj"];

  for (const pattern of filePatterns) {
    const files = await detectFiles(appPath, pattern);
    if (files.length === 0) {
      continue;
    }

    const readPromises = files.map(async (file) => {
      const content = await fs.readFile(path.join(appPath, file), "utf8");
      return content.includes("Crashlytics");
    });

    const results = await Promise.all(readPromises);
    if (results.some((found) => found)) {
      return true;
    }
  }

  return false;
}

While this refactoring is larger than the current change, it would significantly improve the quality of this function.

Copy link
Contributor

@schnecle schnecle Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love Gemini's approach, but we could concat all of the detected files into a single list and loop over that single list. Not a blocking comment, but might be a nice clean up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! Going to go ahead and merge this for now, and will work on the clean up in another PR. Just to verify the process, do we want to first detect each file then read through each one? so it would be something like

Detect Podfile
Detect Package.swift
Detect Cartfile*
Detect project.pbxproj
Read Podfile // If using pods, will return after getting all 4 files
Read Package.swift
Read Cartfile*
Read project.pbxproj

I think it would be better if we do something like the current implementation since we can return early once we read the file has Crashlytics

Detect Podfile
Read Podfile // If using pods, returns after getting Podfile
Detect Package.swift
Read Package.swift
Detect Cartfile*
Read Cartfile*
Detect project.pbxproj
Read project.pbxproj

Let me know if I misunderstood anything here.

Copy link
Contributor

@schnecle schnecle Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was suggesting the first one --

Detect Podfile
Detect Package.swift
Detect Cartfile*
Detect project.pbxproj
Read Podfile // If using pods, will exit here
Read Package.swift
Read Cartfile*
Read project.pbxproj

The file detection is just looking matching file names. It is slightly less efficient in that we are going to try to detect all the different file patterns, but we still have the opportunity to exit early if we find what we are looking for. It would make the code a lot cleaner because it would be something like --

const fileArrays = await Promises.all(
  detectFiles(appPath, "Podfile"), 
  detectFiles(appPath, "Package.swift"),
  detectFiles(appPath, "Cartfile*"),
  detectFiles(appPath, "project.pbxproj"));

const files = fileArrays.flat();

if (files.length === 0) {
  return false;
}

for (const file of files) {
  const content = await fs.readFile(path.join(appPath, file), "utf8");
  if (content.includes("Crashlytics")) {
    return true;
  }
}

return false;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this definitely does look cleaner. I will work on this!

@aalej aalej changed the title fix issue where crashlytics isn't detected for ios apps that use project.pbxproj [mcp] fix issue where crashlytics isn't detected for ios apps that use project.pbxproj Nov 24, 2025
@joehan joehan requested a review from schnecle November 24, 2025 17:13
Copy link
Contributor

@schnecle schnecle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for responding to this one! LGTM!

Comment on lines +83 to +89
const xcodeProjectFiles = await detectFiles(appPath, "project.pbxproj");
for (const file of xcodeProjectFiles) {
const content = await fs.readFile(path.join(appPath, file), "utf8");
if (content.includes("Crashlytics")) {
return true;
}
}
Copy link
Contributor

@schnecle schnecle Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love Gemini's approach, but we could concat all of the detected files into a single list and loop over that single list. Not a blocking comment, but might be a nice clean up.

@aalej aalej merged commit e8cd1ba into master Nov 25, 2025
48 checks passed
@aalej aalej deleted the aalej_fix-mcp-ioscrashlytics-detect branch November 25, 2025 13:45
@github-project-automation github-project-automation bot moved this from Approved [PR] to Done in [Cloud] Extensions + Functions Nov 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants